如何将XmlDocument.SelectSingleNode()与默认名称空间一起使用?

时间:2018-08-09 21:55:31

标签: c# xml xpath xmldocument system.xml

我正在尝试使用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以显示更多结构。问题似乎与将默认名称空间应用于文档的部分而不是整个文档有关。

2 个答案:

答案 0 :(得分: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();
        }
    }
}

答案 1 :(得分:0)

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

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

doc.setProperty("SelectionNamespaces", "xmlns:abc='http://tempuri.org/Ticket.xsd'");
doc.selectSingleNode("//abc:TicketNumber");