Xml parsing in ruby

Hi,

I am very new to ruby programming and therefore, facing problem in xml
parsing in ruby. The problem is to parse an xml file(xmlfile.xml) in
ruby that should generate a code which should look like as under:

<declaration>typedef int[0,2] StateTC;
const StateTC TC_ACTIVE = 0;
const StateTC TC_COMPLETING = 1;
const StateTC TC_ENDED = 2;

StateTC stTC = TC_ACTIVE;

typedef int[0,2] StateP;
const StateP P_ACTIVE = 0;
const StateP P_COMPLETING = 1;
const StateP P_ENDED = 2;

StateP stP = P_ACTIVE;

typedef int[0,1] MsgsTC;
const MsgsTC PREPARE_TC = 0;
bool msgsTc[MsgsTC];

typedef int[0,1] MsgsP;
const MsgsP COMPLETE_P = 0;
bool msgsP[MsgsP];

</declaration>

I attach 2 files: xmlfile(source file), rubyfile(my try). Can you please
help me in writing ruby code that generates output as shown above from
xmlfile.

Thanks in advance.

Regards,
Salim

Attachments:
http://www.ruby-forum.com/attachment/5558/xmlfile.xml
http://www.ruby-forum.com/attachment/5559/rubyfile.rb

···

--
Posted via http://www.ruby-forum.com/.

Have you looked into nokogiri?

···

Sent from my iPhone

On Dec 15, 2010, at 9:43 AM, Salim Reza <saleem.vighio@gmail.com> wrote:

Hi,

I am very new to ruby programming and therefore, facing problem in xml
parsing in ruby. The problem is to parse an xml file(xmlfile.xml) in
ruby that should generate a code which should look like as under:

<declaration>typedef int[0,2] StateTC;
const StateTC TC_ACTIVE = 0;
const StateTC TC_COMPLETING = 1;
const StateTC TC_ENDED = 2;

StateTC stTC = TC_ACTIVE;

typedef int[0,2] StateP;
const StateP P_ACTIVE = 0;
const StateP P_COMPLETING = 1;
const StateP P_ENDED = 2;

StateP stP = P_ACTIVE;

typedef int[0,1] MsgsTC;
const MsgsTC PREPARE_TC = 0;
bool msgsTc[MsgsTC];

typedef int[0,1] MsgsP;
const MsgsP COMPLETE_P = 0;
bool msgsP[MsgsP];

</declaration>

I attach 2 files: xmlfile(source file), rubyfile(my try). Can you please
help me in writing ruby code that generates output as shown above from
xmlfile.

Thanks in advance.

Regards,
Salim

Attachments:
http://www.ruby-forum.com/attachment/5558/xmlfile.xml
http://www.ruby-forum.com/attachment/5559/rubyfile.rb

--
Posted via http://www.ruby-forum.com/\.

Daniel Zd wrote in post #968678:

Have you looked into nokogiri?

Sent from my iPhone

No, I could not find it. When did you sent it?

···

--
Posted via http://www.ruby-forum.com/\.

Salim Reza wrote in post #968699:

Daniel Zd wrote in post #968678:

Have you looked into nokogiri?

Sent from my iPhone

No, I could not find it. When did you sent it?

Ok. I tried to look into nokogiri but I could not solve my problem yet.
Perhaps, i still need help.

···

--
Posted via http://www.ruby-forum.com/\.

Salim,

Why the second "<role name" = par?
But there's const StateP (P not PAR).
Wouldn't it be StatePAR ?

If PAR, something like this would solve half of the problem.

It's still ugly code... but, we can improve it together.

require 'rexml/document'
include REXML
file = File.new("xmlfile.xml")
doc = Document.new(file)

doc.elements.each("protocol/role") do |r|
  role = r.attributes["name"].upcase
  states = r.get_elements("states/state")

  # First line
  stm = "typedef int[0,%d] State%s;\n" % [states.size-1, role]

  states.each_with_index do |s, ix|
    # One line for each state
    state = "const State%s %s = %d;\n" % [ role, s.text.upcase, ix]
    stm << state
  end
  puts stm
  puts
end

But, if it's really "P" then we could get the "P" "regexping" the
states for the part before the underline signal.

What language is this?

···

On Wed, Dec 15, 2010 at 4:28 PM, Salim Reza <saleem.vighio@gmail.com> wrote:

Salim Reza wrote in post #968699:

Daniel Zd wrote in post #968678:

Have you looked into nokogiri?

Sent from my iPhone

No, I could not find it. When did you sent it?

Ok. I tried to look into nokogiri but I could not solve my problem yet.
Perhaps, i still need help.

--
Posted via http://www.ruby-forum.com/\.

Typically you'll get more and better answers if you ask more specific questions. What does not work in your code? What error do you see? These kinds of things.

Cheers

  robert

···

On 15.12.2010 21:28, Salim Reza wrote:

Salim Reza wrote in post #968699:

Daniel Zd wrote in post #968678:

Have you looked into nokogiri?

No, I could not find it. When did you sent it?

Ok. I tried to look into nokogiri but I could not solve my problem yet.
Perhaps, i still need help.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Abinoam Jr. wrote in post #968720:

Salim,

Hi Abinoam,

I am really grateful to you for your immense help.

Why the second "<role name" = par?
But there's const StateP (P not PAR).
Wouldn't it be StatePAR ?

You are right. It should be "PAR" instead of "P" (that is: StatePAR) in
order to maintain the consistency and easiness.

I have extended your help_code to messages. However, output result
appends all messages to each role, whereas each role(TC and PAR) should
have its own messages list. For example: I need:
typedef int[0,1] MsgsTC;
const MsgsTC PREPARE_TC = 0;
bool msgsTc[MsgsTC]; as an out put. But my output shows:

typedef int[0,1] MsgsTC;
const MsgsTC PREPARE_TC = 0;
const MsgsTC COMPLETE_PAR = 1; that means it also appends message from
the PAR role which should not happen. I do not understand how do
decrease ranges. Though I have tried.

I attach again revised xmlfile.xml and rubyfile.rb. Please help.

What language is this?

This is C/C++ based language used by Uppaal tool.

Thanks once again for help.

Attachments:
http://www.ruby-forum.com/attachment/5564/xmlfile.xml
http://www.ruby-forum.com/attachment/5565/rubyfile.rb

···

--
Posted via http://www.ruby-forum.com/\.

Salim,

I have "finished" the script.
It's getting uglier at each interaction. (needs refactoring)
But, it seems to work well.

I renamed to xml2uppall.rb.
There's 2 xml. The second is a modified version just for put the
script to proof.
Each cpp file corresponds to an xml file.

Tell me if it works for you.

Tell me if you don't understand any part of the code.

Abinoam Jr.

xml2uppaal.rb (1.17 KB)

xmlfile.xml (1.26 KB)

uppaal.cpp (468 Bytes)

xmlfile2.xml (1.37 KB)

uppaal2.cpp (575 Bytes)

···

On Thu, Dec 16, 2010 at 8:47 AM, Salim Reza <saleem.vighio@gmail.com> wrote:

Abinoam Jr. wrote in post #968720:

Salim,

Hi Abinoam,

I am really grateful to you for your immense help.

Why the second "<role name" = par?
But there's const StateP (P not PAR).
Wouldn't it be StatePAR ?

You are right. It should be "PAR" instead of "P" (that is: StatePAR) in
order to maintain the consistency and easiness.

I have extended your help_code to messages. However, output result
appends all messages to each role, whereas each role(TC and PAR) should
have its own messages list. For example: I need:
typedef int[0,1] MsgsTC;
const MsgsTC PREPARE_TC = 0;
bool msgsTc[MsgsTC]; as an out put. But my output shows:

typedef int[0,1] MsgsTC;
const MsgsTC PREPARE_TC = 0;
const MsgsTC COMPLETE_PAR = 1; that means it also appends message from
the PAR role which should not happen. I do not understand how do
decrease ranges. Though I have tried.

I attach again revised xmlfile.xml and rubyfile.rb. Please help.

What language is this?

This is C/C++ based language used by Uppaal tool.

Thanks once again for help.

Attachments:
http://www.ruby-forum.com/attachment/5564/xmlfile.xml
http://www.ruby-forum.com/attachment/5565/rubyfile.rb

--
Posted via http://www.ruby-forum.com/\.

Abinoam Jr. wrote in post #968849:

Salim,

I have "finished" the script.
It's getting uglier at each interaction. (needs refactoring)
But, it seems to work well.

I renamed to xml2uppall.rb.
There's 2 xml. The second is a modified version just for put the
script to proof.
Each cpp file corresponds to an xml file.

Tell me if it works for you.

Tell me if you don't understand any part of the code.

Abinoam Jr.

Hi Abinoam,

It works as intended. Thanks for the help. I have understood most of the
code. Except: ARGV[0].nil? ? "xmlfile.xml" : ARGV[0] and
Regexp.new(/\w*_(\w*)/). I am trying to take a look about these from
tutorials.

Thanks once again.

···

--
Posted via http://www.ruby-forum.com/\.

(ARGV[0].nil?) ? ("xmlfile.xml") : (ARGV[0])

The first ARGV is nil? The user didn't suplied any command line argument?
So use the "xmlfile.xml" as default.
Else, use the filename suplied by the user.

Try "xml2uppaal.rb xmlfile2.xml".

Regexp.new(/\w*_(\w*)/)

Search for something in the form of (anyword) + an underline +
(anyword) and "save" the word after the underline.

"\w*_(\w*)"

\w (any word character)
* 1 or more times
() delimiter for retrieving it after the search.

Play around with this site.

···

On Thu, Dec 16, 2010 at 3:26 PM, Salim Reza <saleem.vighio@gmail.com> wrote:

Abinoam Jr. wrote in post #968849:

Salim,

I have "finished" the script.
It's getting uglier at each interaction. (needs refactoring)
But, it seems to work well.

I renamed to xml2uppall.rb.
There's 2 xml. The second is a modified version just for put the
script to proof.
Each cpp file corresponds to an xml file.

Tell me if it works for you.

Tell me if you don't understand any part of the code.

Abinoam Jr.

Hi Abinoam,

It works as intended. Thanks for the help. I have understood most of the
code. Except: ARGV[0].nil? ? "xmlfile.xml" : ARGV[0] and
Regexp.new(/\w*_(\w*)/). I am trying to take a look about these from
tutorials.

Thanks once again.

--
Posted via http://www.ruby-forum.com/\.

Abinoam Jr. wrote in post #968957:

(ARGV[0].nil?) ? ("xmlfile.xml") : (ARGV[0])

The first ARGV is nil? The user didn't suplied any command line
argument?
So use the "xmlfile.xml" as default.
Else, use the filename suplied by the user.

Try "xml2uppaal.rb xmlfile2.xml".

Regexp.new(/\w*_(\w*)/)

Search for something in the form of (anyword) + an underline +
(anyword) and "save" the word after the underline.

"\w*_(\w*)"

\w (any word character)
* 1 or more times
() delimiter for retrieving it after the search.

Play around with this site.
http://www.rubular.com/

Thanks Abinoam.

Regards,
Salim

···

--
Posted via http://www.ruby-forum.com/\.