使用XPath解析XML文档
可以说我有以下xml(一个简单的例子)
one two
我试图通过使用XmlDocument和XPath解析这个(最终我可以创建行列表)。
例如…
XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); foreach(XmlNode row in doc.SelectNodes("//row")) { string rowName = row.SelectSingleNode("//name").InnerText; }
为什么在我的foreach循环中,rowName总是“一个”? 我希望它在第一次迭代时是“一个”,在第二次迭代时是“两个”。
似乎// name获取文档中的第一个实例,而不是我期望的行中的第一个实例。 毕竟,我在“行”节点上调用该方法。 如果这是“它是如何工作的”那么任何人都可以解释我如何改变它以满足我的需求?
谢谢
XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); foreach(XmlNode row in doc.SelectNodes("//row")) { var rowName = row.SelectSingleNode("name"); }
您发布的代码实际上是否正确? 我在row.SelectNode()上遇到编译错误,因为它不是XmlNode的成员。
无论如何,我上面的示例有效,但假设
节点中只有一个
节点,因此如果不是这样,您可能需要使用SelectNodes()
而不是SelectSingleNode()
。
正如其他人所示,使用.InnerText
来获取值。
使用LINQ to XML。 包括using System.Xml.Linq;
在您的代码文件中,然后执行以下代码以获取列表
XDocument xDoc = XDocument.Load(filepath); IEnumerable xNames; xNames = xDoc.Descendants("name");
这将为您提供名称元素的列表。 然后,如果要将其转换为List
只需执行以下操作:
List list = new List (); foreach (XElement element in xNames) { list.Add(element.value); }
你的第二个xpath以//
开头。 这是/descendant-or-self::node()
的缩写,你可以看到它以/
开头,这意味着它从文档的根目录搜索,无论你使用它的上下文。
你可能想要一个:
var rowName = row.SelectSingleNode("name");
找到该row
直接子节点的name
节点,或
var rowName = row.SelectSingleNode(".//name");
在行下the
任何位置查找name
节点* . Note the
. Note the
第二个xpath中. Note the
.`,它导致xpath从上下文节点开始。
使用相对路径,例如string rowName = row.SelectSingleNode("name").InnerText;
。
问题出在你的第二个XPath查询中:
//row
这具有全局范围,因此无论您从何处调用它,它都将选择所有 row
元素。
如果用以下代码替换表达式,它应该有效:
.//row
我会使用SelectSingleNode,然后使用InnerText属性。
var rowName = row.SelectSingleNode("name").InnerText;
使用以下内容
doc.LoadXml(xml); foreach(XmlNode row in doc.SelectNodes("/rows/row")) { string rowName = row.SelectSingleNode("//name").InnerText.ToString(); }