MadsTheMan
MadsTheMan

Reputation: 703

How can I select a specific XML node and fetch the values in its child nodes

I'm trying to select a specific node and fetch the values in it's childnodes. This would normally be pretty easy, but the complication is that the nodes have the same name. My xml looks something like this;

<Settings>
  <Config>
  </Config>
  <Items>
    <Item>
      <ID>Hello</ID>
      <Pth>Somevalue</Pth>
      <Zvb>True</Zvb>
      <Ico>True</Ico>
    </Item>
    <Item>
      <ID>Stack</ID>
      <Pth>Somevalue</Pth>
      <Zvb>False</Zvb>
      <Ico>True</Ico>
    </Item>
    <Item>
      <ID>Overflow</ID>
      <Pth>Somevalue</Pth>
      <Zvb>False</Zvb>
      <Ico>True</Ico>
    </Item>
  </Items>
</Settings>

Each <ID>'s innertext is always unique. I now want to select the <Item> ,where it's <ID>'s innertext is "Stack". (I need the other childnode-values as well, like Pth, Zvb and Ico. So everything under <Item> basically)

I did this is powershell, and it looks something like this;

$script:specificItem = $dgvItems.rows[$_.RowIndex].Cells[1].Value
$script:fetch = @($xml.SelectNodes('//Item')) | Select-Object * | Where { $_.ID -like $specificItem }

So far I've got this (I'm in a RowEnter event of a datagridview):

XmlDocument xml = new XmlDocument();
xml.Load(GlobalVars.configfile);

int rowindex = dgvItemlist.CurrentCell.RowIndex;
dgvItemlist.Rows[rowindex].Cells[2].Value.ToString(); //This will contain for example "Stack"

XmlNodeList Items = xml.SelectNodes("//Items/Item"); //probably other ways to start as well

... but from here I struggle with filtering or selecting the one I want. I know this is a fairly common question, but I can't find a good solution for this exact issue.

Upvotes: 0

Views: 1971

Answers (3)

Sachin Sathe
Sachin Sathe

Reputation: 29

Try the following. It will return the specific node you are looking for.

XmlNode itemNode = doc.SelectSingleNode("//ID[text()='Stack']").ParentNode;

Upvotes: 1

Magnetron
Magnetron

Reputation: 8543

You could also use XDocument (Linq to XML):

string xml =@"<Settings>
  <Config>
  </Config>
  <Items>
    <Item>
      <ID>Hello</ID>
      <Pth>Somevalue</Pth>
      <Zvb>True</Zvb>
      <Ico>True</Ico>
    </Item>
    <Item>
      <ID>Stack</ID>
      <Pth>Somevalue</Pth>
      <Zvb>False</Zvb>
      <Ico>True</Ico>
    </Item>
    <Item>
      <ID>Overflow</ID>
      <Pth>Somevalue</Pth>
      <Zvb>False</Zvb>
      <Ico>True</Ico>
    </Item>
  </Items>
</Settings>";

XDocument xdoc = XDocument.Parse(xml);
XElement desired = xdoc.Descendants("Item").FirstOrDefault(x=>(string)x.Element("ID")=="Stack");
if(desired!=null)
{
    string Pth = (string)desired.Element("Pth");
    string Zvb = (string)desired.Element("Zvb");
    string Ico = (string)desired.Element("Ico");
}

desired will be the wanted element.

Upvotes: 2

Pierre Fran&#231;ois
Pierre Fran&#231;ois

Reputation: 6061

Try to change the last line of your code into:

XmlNodeList Items = xml.SelectNodes("//Items/Item[ID='Stack']"); 

This should return:

<Item>
  <ID>Stack</ID>
  <Pth>Somevalue</Pth>
  <Zvb>False</Zvb>
  <Ico>True</Ico>
</Item>

Upvotes: 1

Related Questions