2

Hi Not sure if this can be done but I know someone here will know :)

using

XElement oNodeEquip = xmlDoc.XPathSelectElement("//ItemAry/Item/Equip");

how would I select Equip from the second in the following:

<TestInfo>
  <ItemAry>
    <Item>
      <testData>ABC</testData>
    </Item>
    <Item>
      <testData>XYZ</testData>
      <Equip>xxx</Equip>
    </Item>
  </ItemAry>
</TestInfo>

there will always be at lease 2 <Item> and the node I want the value from will always be in the second <Item>

this is a WPF app using .Net 4.0

Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
Adrian
  • 1,089
  • 24
  • 51
  • Wouldn't a more suitable example have an `` element in the first `` element, as well? – O. R. Mapper Nov 27 '12 at 10:00
  • Hi O R Mapper, thanks but in the real XML Equip only ever appears in the second item never in the first so wanted to keep the example the same. – Adrian Nov 27 '12 at 10:11
  • Only ever in the second item? i.e. Never in the first, and never in the third or later items? If so, doesn't your XPath expression already work? – O. R. Mapper Nov 27 '12 at 10:12
  • Ok sorry not giving the full story, currently it is in the first Item, soon it will be in both the first and second for cut over period and then only in the second. thus I want to deploy this during the phase it is in both and not have to make any further changes. thanks for your help and interest your solution seems to work fine for me. – Adrian Nov 27 '12 at 10:24

4 Answers4

3

Try this XPath expression:

//ItemAry/Item[2]/Equip

It considers only the second <Item> element.

O. R. Mapper
  • 20,083
  • 9
  • 69
  • 114
1

You can easily do it with Linq to Xml:

XDocument xdoc = XDocument.Load(path_to_xml);
var second = (string)xdoc.Descendants("Item").Skip(1).Element("Equip");
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • 1
    Hi thanks for this answer and will keep it in mind, but just need a quick fix to existing code using xpath. – Adrian Nov 27 '12 at 10:12
1

Use:

(/*/ItemAry/Item)[2]/Equip

The currently selected answer can produce unexpected results, depending on the specific XML document at hand:

//ItemAry/Item[2]/Equip

selects the Equip children of all Item elements that are the second Item child of their ItemAry parent.

So, if the source XML document is:

<TestInfo>
  <ItemAry>
    <Item>
      <testData>ABC</testData>
    </Item>
    <Item>
      <testData>XYZ</testData>
      <Equip>xxx</Equip>
    </Item>
  </ItemAry>
  <ItemAry>
    <Item>
      <testData>DEF</testData>
    </Item>
    <Item>
      <testData>TUW</testData>
      <Equip>yyy</Equip>
    </Item>
  </ItemAry>
</TestInfo>

the above potentially-wrong expression selects two elements:

<Equip>xxx</Equip>
<Equip>yyy</Equip>

The correct expression provided in this answer:

(/*/ItemAry/Item)[2]/Equip

selects just:

<Equip>xxx</Equip>
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
0

If you are ceratin about position of the node, you can use position() function in your XPath:

XElement oNodeEquip = xmlDoc.XPathSelectElement("//ItemAry/Item[position()=2]/Equip");
VMAtm
  • 27,943
  • 17
  • 79
  • 125