I'm querying Sharepoint server-side and getting back results as Xml. I want to slim down the Xml into something more lightweight before sending it to jQuery through a WebMethod.
However my XPath query isn't working. I thought the following code would return all Document nodes, but it returns nothing. I've used XPath a little before, I thought //Document
do the trick.
C# XPath query
XmlDocument xmlResults = new XmlDocument();
xmlResults.LoadXml(xml); // XML is a string containing the XML source shown below
XmlNodeList results = xmlResults.SelectNodes("//Document");
XML being queried
<ResponsePacket xmlns="urn:Microsoft.Search.Response">
<Response domain="QDomain">
<Range>
<StartAt>1</StartAt>
<Count>2</Count>
<TotalAvailable>2</TotalAvailable>
<Results>
<Document relevance="126" xmlns="urn:Microsoft.Search.Response.Document">
<Title>Example 1.doc</Title>
<Action>
<LinkUrl size="32256" fileExt="doc">http://hqiis99/Mercury/Mercury documents/Example 1.doc</LinkUrl>
</Action>
<Description />
<Date>2010-08-19T14:44:56+01:00</Date>
</Document>
<Document relevance="31" xmlns="urn:Microsoft.Search.Response.Document">
<Title>Mercury documents</Title>
<Action>
<LinkUrl size="0" fileExt="aspx">http://hqiis99/mercury/Mercury documents/Forms/AllItems.aspx</LinkUrl>
</Action>
<Description />
<Date>2010-08-19T14:49:39+01:00</Date>
</Document>
</Results>
</Range>
<Status>SUCCESS</Status>
</Response>
</ResponsePacket>
You're trying to select Document
elements which don't have a namespace... whereas the default namespace is actually "urn:Microsoft.Search.Response" here.
I think you want something like this:
XmlDocument xmlResults = new XmlDocument();
xmlResults.LoadXml(xml);
XmlNamespaceManager manager = new XmlNamespaceManager(xmlResults.NameTable);
manager.AddNamespace("ns", "urn:Microsoft.Search.Response.Document");
XmlNodeList results = xmlResults.SelectNodes("//ns:Document", manager);
This finds two elements.
If you can use LINQ to XML instead, it makes it all somewhat easier:
XDocument results = XDocument.Parse(xml);
XNamespace ns = "urn:Microsoft.Search.Response.Document";
var documents = results.Descendants(ns + "Document");
I love LINQ to XML's namespace handling :)
Alternatively, you could try the following and ignore the namespaces:
XmlDocument xmlResults = new XmlDocument();
xmlResults.LoadXml(xmlString);
XmlNodeList results = xmlResults.SelectNodes("//*[local-name()='Document']");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With