[英]Using XPath to parse an XML document
Lets say I have the following xml (a quick example) 可以说我有以下xml(一个简单的例子)
<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). 我试图通过使用XmlDocument和XPath解析这个(最终我可以创建行列表)。
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"? 为什么,在我的foreach循环中,rowName总是“一个”? 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. 似乎// name获取文档中的第一个实例,而不是我期望的行中的第一个实例。 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 谢谢
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.
我在row.SelectNode()上遇到编译错误,因为它不是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. 无论如何,我上面的示例有效,但假设
<row>
节点中只有一个<name>
节点,因此如果不是这样,您可能需要使用SelectNodes()
而不是SelectSingleNode()
。
As others have shown, use .InnerText
to get just the value. 正如其他人所示,使用
.InnerText
来获取值。
Use LINQ to XML. 使用LINQ to XML。 Include
using System.Xml.Linq;
包括
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<string> list = new List<string>();
foreach (XElement element in xNames)
{
list.Add(element.value);
}
Your second xpath starts with //
. 你的第二个xpath以
//
开头。 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. 这是
/descendant-or-self::node()
的缩写,您可以看到以/
开头,这意味着它从文档的根目录搜索,无论您使用它的上下文。
You probably want one of: 你可能想要一个:
var rowName = row.SelectSingleNode("name");
to find the name
nodes that are immediate children of the row
, or 找到该
row
直接子节点的name
节点,或
var rowName = row.SelectSingleNode(".//name");
to find name
nodes *anywhere under the
row . Note the
在行下
the
任何位置查找name
节点* . Note the
. Note the
.` in this second xpath that causes the xpath to start from the context node. . Note the
第二个xpath中. Note the
.`,它导致xpath从上下文节点开始。
Use a relative path eg string rowName = row.SelectSingleNode("name").InnerText;
使用相对路径,例如
string rowName = row.SelectSingleNode("name").InnerText;
. 。
The problem is in your second XPath query: 问题出在第二个XPath查询中:
//row
This has a global scope, so no matter where you call it from, it will select all row
elements. 这具有全局范围,因此无论您从何处调用它,它都将选择所有
row
元素。
It should work if you replace your expression with: 如果用以下代码替换表达式,它应该有效:
.//row
我会使用SelectSingleNode,然后使用InnerText属性。
var rowName = row.SelectSingleNode("name").InnerText;
Use the following 使用以下内容
doc.LoadXml(xml);
foreach(XmlNode row in doc.SelectNodes("/rows/row"))
{
string rowName = row.SelectSingleNode("//name").InnerText.ToString();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.