3

我正在尝试使用 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()
    • 尝试 1 返回:767My Customer 1。为什么所有值都连接在一起???
    • 尝试 2 返回:7。看起来不错
  • 获取 Customer_Id
    • XPath://Data/Customer_Id/text()
    • 尝试 1 返回:767My Customer 1。为什么所有值都连接在一起???
    • 尝试 2 返回:7。为什么我会得到 Address_Id?

问题
可能我使用了不正确的 XPath。但我也不明白结果。为了了解发生了什么。我想知道:

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

1 回答 1

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;

但是,您有什么理由在这里使用 XPathXPathDocument吗?我认为使用更具表现力和(更多)静态类型的 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();
于 2015-09-01T16:15:21.190 回答