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