如何使用XPathNodeIterator

时间:2015-09-01 10:03:36

标签: c# xml xpath xpathnavigator

我正在尝试使用XPathNodeIterator从元素中选择值。但是我无法从我的XML文件中获得预期的值。

我的XML文件

<?xml version="1.0" encoding="utf-8"?>
<ns0:Entity xmlns:ns0="http://schemas.mycompany.com/1.0">
    <ns0:Data>
        <Address_Id xmlns:ns0="http://schemas.mycompany.com/1.0">7</Address_Id>
        <Customer_Id xmlns:ns0="http://schemas.mycompany.com/1.0">67</Customer_Id>
        <CustomerName xmlns:ns0="http://schemas.mycompany.com/1.0">My Customer 1</CustomerName>
    </ns0:Data>
</ns0:Entity>

获取值的方法
我已经创建了两种方法,它们都没有返回我想要的值。

private static string GetValue_Attempt1(XPathDocument xPathDocument, string xpathExpression)
{
    var xpathNavigator = xPathDocument.CreateNavigator();
    var xpathNodeIterator = xpathNavigator.Select(xpathExpression);
    xpathNodeIterator.MoveNext();
    return xpathNodeIterator.Current.Value;
}

private static string GetValue_Attempt2(XPathDocument xPathDocument, string xpathExpression)
{
    var xpathNavigator = xPathDocument.CreateNavigator();
    var xpathNodeIterator = xpathNavigator.Select(xpathExpression);
    xpathNodeIterator.MoveNext();
    var nodesNavigator = xpathNodeIterator.Current;
    var nodesText = nodesNavigator.SelectDescendants(XPathNodeType.Text, false);
    nodesText.MoveNext();
    return nodesText.Current.Value;
}

我的XPath

  • 获取地址_Id
    • XPath://Data/Address_Id/text()
    • Attempt1返回:767My Customer 1。为什么所有值都连接起来???
    • Attempt2返回:7。看起来不错
  • 获取Customer_Id
    • XPath://Data/Customer_Id/text()
    • Attempt1返回:767My Customer 1。为什么所有值都连接起来???
    • Attempt2返回:7。为什么我得到Address_Id ??

问题
可能我使用的是不正确的XPath。但我也不了解结果。为了解最新情况。我想知道:

  1. 有更好的方法(方法)来获取元素的价值吗?
  2. 我需要使用什么XPath字符串?
  3. 为什么方法GetValue_Attempt1会返回一个连续的字符串?
  4. 为什么方法GetValue_Attempt2只返回第一个元素的值?

1 个答案:

答案 0 :(得分:4)

您的XPath没有返回任何匹配项,因为您没有考虑名称空间。

您的'尝试1'会调用MoveNext()一次,因此Value会返回Data中的所有连接文字,而'尝试2'会调用MoveNext()两次,这两个位置你在Address_Id元素内。

此外,Select,即使XPath有效,也不会实际移动光标。

如果你想得到这个值,你会做这样的事情 - 注意我在XPath中包含命名空间并使用SelectSingleNode的结果:

var nsm = new XmlNamespaceManager(new NameTable());
nsm.AddNamespace("ns0", "http://schemas.mycompany.com/1.0");

var value = navigator.SelectSingleNode("//ns0:Data/Address_Id", nsm).Value;

但是,您有什么理由在这里使用XPath和XPathDocument吗?使用更具表现力和(更多)静态类型的LINQ to XML将是更可取的,我认为:

XNamespace ns = "http://schemas.mycompany.com/1.0";

var doc = XDocument.Parse(xml);

var addressId = (int)doc.Descendants(ns + "Data")
    .Elements("Address_Id")
    .Single();

var customerId = (int)doc.Descendants(ns + "Data")
    .Elements("Customer_Id")
    .Single();