Reputation: 25928
I am trying to create an XPath query/string that grabs a specific element from a XML document. I am attempting to grab the element with the id=38 but my code always returns nothing for some reason.
If you look at my code & the organisation of my XML file can you tell me what XPath I need to grab the element with the id=38?
My code is:
XmlDocument xdoc = new XmlDocument();
xdoc.Load(getProductURL());
XmlNode node = xdoc.DocumentElement.SelectSingleNode("id('38')");
// node always is null for some reason?
The way the xml is organised is like so:
<courseg>
<group isempty="False" isbranch="true" id="1" name="abc">
<group isempty="False" isbranch="true" id="38" name="def"></group>
</group>
</courseg>
Upvotes: 14
Views: 20946
Reputation: 163342
The function id('P38') would select an element with an ID value of P38. But this doesn't just mean "an attribute named 'id'". It means an attribute declared in the DTD or schema as being of type ID. You haven't shown a DTD or schema, and I suspect you don't have one. If you did, and if it declared the id attribute as being of type ID, then your document would be invalid, because an ID value cannot be all-numeric (for legacy SGML reasons, it has to take the form of a name).
In practice the id() function is probably best avoided unless you have severe performance requirements. It's too fragile - it only works when you are validating the source document against a schema or DTD. In XSLT, use key() instead. Alternatively, many processors now recognize the attribute name xml:id as a 'self declaring' ID value without reference to a schema or DTD: use that if your processor supports it.
Upvotes: 5
Reputation: 2801
When you mention
xdoc.DocumentElement.SelectSingleNode("id('38')"
you are asking xmldocument to search for a child node inside root node whose name is 'id'. But ideally 'id' is an attribute and not a xmlnode.
So you have to use //group[@id = '38']
to get all child node having name 'group' and attribute 'id' with a value of 38
Upvotes: -1
Reputation: 56172
Use this XPath query:
//*[@id = 38]
It selects every node with id
attribute equals to 38
. If you have to be more specific, i.e. select group
with id
attribute equals to 38
, use this one:
//group[@id = 38]
Upvotes: 4
Reputation: 93030
The XPath you need is
//*[@id='38']
Here is the example with XDocument:
XDocument xdoc = XDocument.Parse(@"
<courseg>
<group isempty=""False"" isbranch=""true"" id=""1"" name=""abc"">
<group isempty=""False"" isbranch=""true"" id=""38"" name=""def""></group>
</group>
</courseg>");
XElement node = xdoc.Root.XPathSelectElement("//*[@id='38']");
Console.WriteLine(node);
Upvotes: 24