Search code examples
rubyxpathrexml

Getting elements in order with REXML XPath


I'd like to iterate through all the <HeadA> and <HeadB> elements in an XML file, and add a unique id to each. The approach I've tried so far is:

@xml.each_element('//HeadA | //HeadB') do |heading|
  #add a new id
end

The problem is, the nodeset from the XPath //HeadA | //HeadB is all the HeadAs followed by all the HeadBs. What I need is an ordered list of all the HeadAs and HeadBs in the order they appear in the document.

Just to clarify, my XML could look like this:

<Doc>
  <HeadA>First HeadA</HeadA>
  <HeadB>First HeadB</HeadB>
  <HeadA>Second HeadA</HeadA>
  <HeadB>Second HeadB</HeadB>
</Doc>

And what I'm getting from the XPath is:

  <HeadA>First HeadA</HeadA>
  <HeadA>Second HeadA</HeadA>
  <HeadB>First HeadB</HeadB>
  <HeadB>Second HeadB</HeadB>

when what I need to get is the nodes in order:

  <HeadA>First HeadA</HeadA>
  <HeadB>First HeadB</HeadB>
  <HeadA>Second HeadA</HeadA>
  <HeadB>Second HeadB</HeadB>

so I can add the ids sequentially.


Solution

  • Ok, 2nd try, but I think I've got it this time :P

    @xml.each_element('//*[self::HeadA or self::HeadB]') do |heading|
      puts heading.text
    end