Using XPath to parse an XML document

♀尐吖头ヾ 提交于 2019-12-30 07:59:10

问题


Lets say I have the following xml (a quick example)

<rows>
   <row>
      <name>one</name>
   </row>
   <row>
      <name>two</name>
   </row>
</rows>

I am trying to parse this by using XmlDocument and XPath (ultimately so I can make a list of rows).

For example...

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

foreach(XmlNode row in doc.SelectNodes("//row"))
{
   string rowName = row.SelectSingleNode("//name").InnerText;
}

Why, within my foreach loop, is rowName always "one"? I am expecting it to be "one" on the first iteration and "two" on the second.

It seems that //name gets the first instance in the document, rather than the first instance in the row as I would expect. After all, I am calling the method on the "row" node. If this is "just how it works" then can anybody please explain how I could change it to work to my needs?

Thank you


回答1:


XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

foreach(XmlNode row in doc.SelectNodes("//row"))
{
   var rowName = row.SelectSingleNode("name");
}

Is the code you posted actually correct? I get a compile error on row.SelectNode() as it isn't a member of XmlNode.

Anyway, my example above works, but assumes only a single <name> node within the <row> node so you may need to use SelectNodes() instead of SelectSingleNode() if that is not the case.

As others have shown, use .InnerText to get just the value.




回答2:


Use LINQ to XML. Include using System.Xml.Linq; in your code file and then do the following code to get your list

XDocument xDoc = XDocument.Load(filepath);
IEnumerable<XElement> xNames;

xNames = xDoc.Descendants("name");

That will give you a list of the name elements. Then if you want to turn that into a List<string> just do this:

List<string> list = new List<string>();
foreach (XElement element in xNames)
{
    list.Add(element.value);
}



回答3:


Your second xpath starts with //. This is an abbreviation for /descendant-or-self::node(), which you can see starts with /, meaning it searches from the root of the document, whatever the context in which you use it.

You probably want one of:

var rowName = row.SelectSingleNode("name");

to find the name nodes that are immediate children of the row, or

var rowName = row.SelectSingleNode(".//name");

to find name nodes *anywhere undertherow. Note the.` in this second xpath that causes the xpath to start from the context node.




回答4:


Use a relative path e.g. string rowName = row.SelectSingleNode("name").InnerText;.




回答5:


The problem is in your second XPath query:

//row

This has a global scope, so no matter where you call it from, it will select all row elements.

It should work if you replace your expression with:

.//row



回答6:


I would use SelectSingleNode, and then the InnerText property.

var rowName = row.SelectSingleNode("name").InnerText;



回答7:


Use the following

        doc.LoadXml(xml);

            foreach(XmlNode row in doc.SelectNodes("/rows/row"))
            {
                string rowName = row.SelectSingleNode("//name").InnerText.ToString();
            }


来源:https://stackoverflow.com/questions/8299069/using-xpath-to-parse-an-xml-document

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!