C# 如何在XDocument中使用XPath?

C# 如何在XDocument中使用XPath?,c#,.net,xml,xpath,linq-to-xml,C#,.net,Xml,Xpath,Linq To Xml,有一个类似的问题,但在我的案例中,解决方案似乎不起作用: 以下是我正在使用的XML: <?xml version="1.0" encoding="utf-8"?> <Report Id="ID1" Type="Demo Report" Created="2011-01-01T01:01:01+11:00" Culture="en" xmlns="http://demo.com/2011/demo-schema"> <ReportInfo>

有一个类似的问题,但在我的案例中,解决方案似乎不起作用:

以下是我正在使用的XML:

<?xml version="1.0" encoding="utf-8"?>
<Report Id="ID1" Type="Demo Report" Created="2011-01-01T01:01:01+11:00" Culture="en" xmlns="http://demo.com/2011/demo-schema">
    <ReportInfo>
        <Name>Demo Report</Name>
        <CreatedBy>Unit Test</CreatedBy>
    </ReportInfo>
</Report>
有人有什么想法吗?
谢谢。

如果您有XDocument,那么使用LINQ到XML更容易:

var document = XDocument.Load(fileName);
var name = document.Descendants(XName.Get("Name", @"http://demo.com/2011/demo-schema")).First().Value;
如果您确定XPath是您需要的唯一解决方案:

using System.Xml.XPath;

var document = XDocument.Load(fileName);
var namespaceManager = new XmlNamespaceManager(new NameTable());
namespaceManager.AddNamespace("empty", "http://demo.com/2011/demo-schema");
var name = document.XPathSelectElement("/empty:Report/empty:ReportInfo/empty:Name", namespaceManager).Value;

MS实现的XPath 1.0没有默认名称空间的概念。所以试试这个:

XDocument xdoc = XDocument.Load(@"C:\SampleXML.xml");
XmlNamespaceManager xnm = new XmlNamespaceManager(new NameTable()); 
xnm.AddNamespace("x", "http://demo.com/2011/demo-schema");
Console.WriteLine(xdoc.XPathSelectElement("/x:Report/x:ReportInfo/x:Name", xnm) == null);

您可以使用不带命名空间的-for your中的示例:

using System.Xml.Linq;
using System.Xml.XPath;
var e = xdoc.XPathSelectElement("./Report/ReportInfo/Name");     

应该这样做

您的回答意味着XPath 2.0,与XPath 1.0相比,“*有一个默认名称空间的“想法”。我不知道这种新的XPath特性(我们这里讨论的是XPath,不是XSLT或XQuery)。因此,请您在回答中明确说明您的意思好吗?我想他在这里得到的是,如果您有一个定义名称空间的文档,您的xpath必须包含限定元素,即您不能执行xnm.AddNamespace(string.Empty,”);然后是xdoc.XPathSelectElement(“/Report/ReportInfo/Name”,xnm)——结果总是为空——我想说,在大多数情况下,很难说linq比xpath容易。例如,在本例中,LINQ等价物并不是真正等价的,因为它还将在其他节点下获得“Name”节点(这些节点现在不存在,但可以通过稍后对文件格式的更改添加)。但是,您的解决方案肯定是正确的;这非常重要,因为XPathSelectElement是一个扩展方法。不要像我那样做,忽略那部分;)XPath仍然很有用,因为它允许您将父子关系上下文化。例如,如果你想进入/Banana/Banana/Banana,而不是让每个香蕉都“空”的话,这有点误导和混淆。除了XPath,您可以使用String.Empty以外的任何东西(如询问者所发现的)。“demo”更适合于该示例。请参见下面的另一个答案,它不起作用,因为XPath 1.0实现无法处理空前缀。如本文所述,在向[XmlNamespaceManager]添加名称空间时,不要使用空前缀。我只是添加了这个注释,以防有人想看到一个带有多个[xmlns]属性(带后缀和不带后缀)的文档的小代码示例。请看这里:
using System.Xml.Linq;
using System.Xml.XPath;
var e = xdoc.XPathSelectElement("./Report/ReportInfo/Name");