tags:

views:

50

answers:

1

I'm having a problem with reading and processing a xml file, which I cannot solve right now. The xml has the following structure:

<root>
  <test id="1">
    <a></a>
    <b></b>
    <c></c>
  </test>
  <test id="2">
    <a></a>
    <b></b>
    <c></c>
  </test>
  <test id="3">
    <a></a>
    <b></b>
    <c></c>
  </test>
</root>



XmlDocument Doc; int currentid=1; 


XmlNode currentlyselectedtestnode =
Doc.SelectNodes("//test[@id = '" +
currentid.ToString() + "']");

string a = currentlyselectedtestnode.SelectSingleNode("//a");    
string b = currentlyselectedtestnode.SelectSingleNode("//b");   
string c = currentlyselectedtestnode.SelectSingleNode("//c");

Unfortunately, "currentlyselectedtestnode.SelectSingleNode("//a")" will read out all "a"-nodes and not only the one that belongs to test-node with id 1. Why ?! Somehow currentlyselectedtestnode.SelectSingleNode("//a"); works just as if I wrote Doc.SelectSingleNode("//a");

How come ?! How can I make it read the children of the specific test-node only ?ectedtestnode.SelectSingleNode("//c");

+4  A: 

When using //a in XPath, you are selecting all a nodes in the document.

If you want the direct child, you need to use currentlyselectedtestnode.SelectSingleNode("a").

See XPath Syntax on w3schools:

// - Selects nodes in the document from the current node that match the selection no matter where they are

You can select all a nodes that are under the current node by using .//a. This will select all child a nodes of the current node, regardless of how deeply nested they are.

Oded
Or, if they can be nested deeply inside the current node, you can use `.//a`.
Tomalak
@Tomalak - thanks for pointing this out. Will add to answer.
Oded
Oh, that gets me closer to the solution.How come that it makes a difference whether I use XmlNode currentlyselectedtestnode = Doc.SelectNodes("//test[@id = '" + currentid.ToString() + "']");or XmlNode currentlyselectedtestnode = Doc.SelectNodes("test[@id = '" + currentid.ToString() + "']");shouldn't it either way select the same single node ?When I do the latter I get a "System.NullReferenceException: Object reference not set to an instance of an object."
dll32
@dll32 - In the second XPath, you are trying to get a _direct_ `test` child node. If one does not exist, `NullReferenceException`. In the first, you are selecting _all_ of the `test` nodes in the document that have the `id` attribute.
Oded
Sure, but in my example with ID="1", both examples should get the same node. Might have an error somewhere else then.
dll32
@dll32 - The root node is called `root` in your document. You can reference it using `/` at the start of the XPath or by name. This should work `/root/test[@id = '" + currentid.ToString() + "']`
Oded