XPathSelectElements returns null

2019-08-31 16:54发布

问题:

Load function is already defined in xmlData class

public class XmlData
{
    public void Load(XElement xDoc)
    {
        var id = xDoc.XPathSelectElements("//ID");
        var listIds = xDoc.XPathSelectElements("/Lists//List/ListIDS/ListIDS");
    }
}

I'm just calling the Load function from my end.

            XmlData aXmlData = new XmlData();

            string input, stringXML = "";
            TextReader aTextReader = new StreamReader("D:\\test.xml");
            while ((input = aTextReader.ReadLine()) != null)
            {
                stringXML += input;
            }
            XElement Content = XElement.Parse(stringXML);
            aXmlData.Load(Content);

in load function,im getting both id and and listIds as null.

My test.xml contains

<SEARCH>
  <ID>11242</ID>
  <Lists>
    <List CURRENT="true" AGGREGATEDCHANGED="false">
      <ListIDS>
        <ListID>100567</ListID>
        <ListID>100564</ListID>
        <ListID>100025</ListID>
        <ListID>2</ListID>
        <ListID>1</ListID>
      </ListIDS>
    </List>
  </Lists>
</SEARCH>

回答1:

EDIT: Your sample XML doesn't have an id element in the namespace with the nss alias. It would be <nss:id> in that case, or there'd be a default namespace set up. I've assumed for this answer that in reality the element you're looking for is in the namespace.

Your query is trying to find an element called id at the root level. To find all id elements, you need:

var tempId = xDoc.XPathSelectElements("//nss:id", ns);

... although personally I'd use:

XDocument doc = XDocument.Parse(...);
XNamespace nss = "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner";
// Or use FirstOrDefault(), or whatever...
XElement idElement = doc.Descendants(nss + "id").Single();

(I prefer using the query methods on LINQ to XML types instead of XPath... I find it easier to avoid silly syntax errors etc.)

Your sample code is also unclear as you're using xDoc which hasn't been declared... it helps to write complete examples, ideally including everything required to compile and run as a console app.



回答2:

I am looking at the question 3 hours after it was submitted and 41 minutes after it was (last) edited.

There are no namespaces defined in the provided XML document.

    var listIds = xDoc.XPathSelectElements("/Lists//List/ListIDS/ListIDS");

This XPath expression obviously doesn't select any node from the provided XML document, because the XML document doesn't have a top element named Lists (the name of the actual top element is SEARCH)

var id = xDoc.XPathSelectElements("//ID");

in load function,im getting both id and and listIds as null.

This statement is false, because //ID selects the only element named ID in the provided XML document, thus the value of the C# variable id is non-null. Probably you didn't test thoroughly after editing the XML document.

Most probably the original ID element belonged to some namespace. But now it is in "no namespace" and the XPath expression above does select it.



回答3:

        string xmldocument = "<response xmlns:nss=\"http://schemas.microsoft.com/SQLServer/reporting/reportdesigner\"><action>test</action><id>1</id></response>";

        XElement Content = XElement.Parse(xmldocument);
        XPathNavigator navigator = Content.CreateNavigator();
        XmlNamespaceManager ns = new XmlNamespaceManager(navigator.NameTable);
        ns.AddNamespace("nss", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner");
        var tempId = navigator.SelectSingleNode("/id");


回答4:

The reason for the null value or system returned value is due to the following

 var id = xDoc.XPathSelectElements("//ID");

XpathSElectElements is System.xml.linq.XElment which is linq queried date. It cannot be directly outputed as such. To Get individual first match element use XPathSelectElement("//ID"); You can check the number of occurrences using XPathSelectElements as

var count=xDoc.XPathSelectElements("//ID").count();

you can also query the linq statement as order by using specific conditions

Inorder to get node value from a list u can use this

foreach (XmlNode xNode in xDoc.SelectNodes("//ListIDS/ListID"))
{
Console.WriteLine(xNode.InnerText);
}

For Second list you havnt got the value since, the XPath for list items is not correct