0

我正在尝试使用 XmlDocument.SelectSingleNode() 从一些客户提供的 XML 文档中提取一些值。

SelectSingleNode() 采用 XPATH 字符串,非常简单的搜索失败。例如:

<?xml version="1.0"?>
<xmlTicket>
    <TicketDataSet xmlns="http://tempuri.org/Ticket.xsd">
        <Ticket>
            <TicketNumber>0123-456-789</TicketNumber>
            ...
        </Ticket>
    </TicketDataSet>
</xmlTicket>

XmlDocument.SelectSingleNode("//TicketNumber") 返回 null。

问题显然是命名空间。如果我从文档中删除 xmlns=,则 XPATH 可以正常工作。如果我使用命名空间中性 XPATH 查询,它们也可以正常工作:

doc.SelectSingleNode("//*[local-name()='TicketNumber']");

但我不能做前者,我宁愿不做后者。

我找到了如何配置命名空间管理器的示例,并试图弄清楚如何使其适用于默认命名空间。

这没有用:

var nsm = new XmlNamespaceManager(doc.NameTable);
nsm.AddNamespace("", "http://tempuri.org/Ticket.xsd");

var ticketNumberNode = doc.SelectSingleNode("//TicketNumber", nsm);

这没有用:

var nsm = new XmlNamespaceManager(doc.NameTable);
nsm.AddNamespace("default", "http://tempuri.org/Ticket.xsd");

var ticketNumberNode = doc.SelectSingleNode("//default:TicketNumber", nsm);

有任何想法吗?

===

注意:我更新了 XML 以显示更多结构。问题似乎与将默认名称空间应用于文档的部分而不是整个文档有关。

4

2 回答 2

0

尝试 xml linq :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            string ticketNumber = (string)doc.Descendants().Where(x => x.Name.LocalName == "TicketNumber").FirstOrDefault();
        }
    }
}
于 2018-08-09T22:17:22.273 回答
0

解决方案很奇怪,但您应该在 SelectionNamespaces 属性中指定带有前缀的命名空间,并在 XPath 查询中指定此前缀。这个命名空间是否是没有前缀的默认命名空间并不重要:你应该使用一个。另一方面,您应该向 XML 添加不带前缀的节点。

在您的示例中,代码应如下所示:

doc.setProperty("SelectionNamespaces", "xmlns:abc='http://tempuri.org/Ticket.xsd'");
doc.selectSingleNode("//abc:TicketNumber");
于 2021-06-10T08:50:47.093 回答