使用XPath解析XML文档
可以说我有下面的XML(一个简单的例子)使用XPath解析XML文档
<rows>
<row>
<name>one</name>
</row>
<row>
<name>two</name>
</row>
</rows>
我尝试使用的XmlDocument和XPath(最终解析这个,所以我可以做出行的列表)。
例如...
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
foreach(XmlNode row in doc.SelectNodes("//row"))
{
string rowName = row.SelectSingleNode("//name").InnerText;
}
为什么,我的foreach循环中,是rowName总是 “一”?我期待它在第一次迭代时是“一”,在第二次时是“二次”。
看起来,//名称在文档中获取第一个实例,而不是我期望的第一个实例。毕竟,我正在调用“行”节点上的方法。如果这是“它是如何工作的”,那么任何人都可以请解释我如何改变它以满足我的需求?
谢谢
是你实际发布的代码是否正确?我在row.SelectNode()上收到一个编译错误,因为它不是XmlNode的成员。
反正我上面的例子作品,但仅假定<row>
节点中的单个节点<name>
,所以你可能需要使用SelectNodes()
而不是SelectSingleNode()
如果情况并非如此。
正如其他人已经表明,使用.InnerText
来得到的价值。
使用相对路径例如string rowName = row.SelectSingleNode("name").InnerText;
。
的问题是在你的第二个XPath查询:
//row
这有一个全球范围内,所以无论你来自哪里调用它,它会选择所有row
元素。
.//row
我会用的SelectSingleNode,然后将InnerText属性:
,如果你与你的替换表达它应该工作。
var rowName = row.SelectSingleNode("name").InnerText;
使用LINQ to XML。包括在你的代码文件using System.Xml.Linq;
然后执行以下代码,让您的列表
XDocument xDoc = XDocument.Load(filepath);
IEnumerable<XElement> xNames;
xNames = xDoc.Descendants("name");
这会给你的名字元素的列表。然后,如果你希望把它转换成一个List<string>
只是这样做:
List<string> list = new List<string>();
foreach (XElement element in xNames)
{
list.Add(element.value);
}
你的第二个XPath与//
开始。这是/descendant-or-self::node()
的缩写,您可以看到它以/
开头,意思是它从文档的根目录搜索,无论您使用它的环境如何。
你可能想的一个:
var rowName = row.SelectSingleNode("name");
找到name
节点是直接子row
的,或
var rowName = row.SelectSingleNode(".//name");
找到下. Note the
the
行的任意name
节点* .`在第二个xpath中导致xpath从上下文节点开始。
使用以下
doc.LoadXml(xml);
foreach(XmlNode row in doc.SelectNodes("/rows/row"))
{
string rowName = row.SelectSingleNode("//name").InnerText.ToString();
}
这会导致同样的问题,因为我不得不开始,对不起 – musefan
让我换句话来说吧,我摆脱了/行,只是做//行,它为我工作。 –
如何有关//行/名称选择呢?这是否工作? – Steve