Basics of XmlNode.SelectNodes?
Asked Answered
S

6

5

I'm not sure why this isn't working.

I have an XmlNode in a known-format. It is:

<[setting-name]>
    <dictionary>
       <[block-of-xml-to-process]/>
       <[block-of-xml-to-process]/>
       <[block-of-xml-to-process]/>
    </dictionary>
</[setting-name]>

I have a reference to the node in a variable called pattern. I want an iterable collection of nodes, each of which is represented by a [block-of-xml-to-process] above. The name and structure of the blocks is unknown at this point. [Setting-name] is known.

This seems pretty straightforward. I can think of a half-dozen XPATH expressions that should point to the blocks. I've tried:

XmlNodeList kvpsList = pattern.SelectNodes(String.Format(@"/{0}/dictionary/*", _CollectionName));
XmlNodeList kvpsList = pattern.SelectNodes(String.Format(@"{0}/dictionary/*", _CollectionName));
XmlNodeList kvpsList = pattern.SelectNodes(@"//dictionary/*");
XmlNodeList kvpsList = pattern.SelectNodes(@"//dictionary");

But, I am apparently lacking some basic understanding of XPATH or some special trick of .SelectNodes because none of them work consistently.

What am I doing wrong?

Schilit answered 30/3, 2009 at 21:51 Comment(4)
You haven't provided some vital necessary information: a complete XML doc, no generalizations, please,; What is the node represented by "pattern"? Maybe it is not the top node of the doc. Finally, what is _collectionname? Can you just give an example with fixed values (stop in the debugger!).Schatz
Mine is not working either. I have an XmlNode object, whose ChildNodes property clearly contains two nodes, both named "wavetrack". Despite this, when I call the XmlNode's SelectNodes("wavetrack") method, the resulting XmlNodeList contains zero elements. This occurs despite variation I've tried for the XPath including "//wavetrack". I have no idea why it's not working, because it seems like it should be straightforward.Bore
Seems to be a known/unexpected behavior: #4272189Bore
See https://mcmap.net/q/631094/-xpath-selectnodes-in-net which solved the problem for me by changing from '//' to './/'Cathedral
M
5

Have you tried removing the "@" from your XPath strings??

XmlNodeList kvpsList = pattern.SelectNodes("//dictionary");

That should work - does work for me on a daily basis :-)

Marc

Madi answered 31/3, 2009 at 5:27 Comment(0)
R
2

Have you tried:

XmlNodeList kvpsList = pattern.SelectNodes(@"//dictionary:child");

OR

XmlNodeList kvpsList = pattern.SelectNodes(@"/[setting-name]/dictionary:child");

Pretty much gets the children of "dictionary" If that doesnt work, does the actual call to dictionary work?

Rasia answered 31/3, 2009 at 0:36 Comment(0)
B
1

I encountered the same problem, and it seems to be a known, but unexpected behavior. See Xml-SelectNodes with default-namespace via XmlNamespaceManager not working as expected

For example, I got it to work by instantiating a XmlNamespaceManager using the XmlDocument's NameTable, then added a namespace with an arbitrary name such as "a" associated with the NamespaceURI of the main document element. Note that the XmlDocument's NamespaceURI was blank in my case, but its DocumentElement's NameSpaceURI actually had a value. That's probably why it wouldn't work without specifying a namespace originally.

XmlDocument doc = new XmlDocument();
doc.Load( file.FullName );
XmlNode docElement = doc.DocumentElement as XmlNode;
XmlNamespaceManager nsman = new XmlNamespaceManager( doc.NameTable );
nsman.AddNamespace( "a", docElement.NamespaceURI );
docElement.SelectNodes( "a:wavetrack", nsman ); //docElement.SelectNodes("wavetrack") wasn't working
Bore answered 29/1, 2013 at 21:21 Comment(0)
L
0

What is the use of variable pattern?
Is it a reference to the DOM of the entire XML?

See what this results into pattern.SelectNodes("//dictionary/").ChildNodes.Count

EDIT: Is this well-formed xml?

Lynsey answered 30/3, 2009 at 21:57 Comment(0)
F
0

Could namespaces be causing a problem? Also, try looking at "pattern.OuterXml" to make sure you are looking at the correct element.

Fidge answered 30/3, 2009 at 21:59 Comment(2)
There are no namespaces defined. And, I've checked the outer XML to make sure that I'm loading what I think I'm loading.Schilit
Then what about just looping through pattern.ChildNodes[0].ChildNodes ?Fidge
R
0

I was just searching for this and found that it worked if you just type:

XmlNodeList kvpsList = pattern.SelectNodes("dictionary");

kvpsList will then contain all [block-of-xml-to-process]-s, though I cannot see why. =')

Raft answered 5/4, 2012 at 20:59 Comment(1)
This is not working for me. I have a node that contains two "wavetrack" nodes (it's an Audacity Project file). Yet, when I call SelectNodes("wavetrack"), it returns zero elements. Seems to be a known/unexpected behavior: #4272189Bore

© 2022 - 2024 — McMap. All rights reserved.