如何使用现有命名空间的xpath查询xml元素

时间:2011-09-30 15:29:23

标签: c# linq-to-xml

<?xml version="1.0" encoding="utf-8"?> 
<Report p1:schemaLocation="TemplateXXX http://localhost?language=en" Name="TemplateXXX" xmlns:p1="http://www.w3.org/2001/XMLSchema-instance" xmlns="TemplateXXX"> 
   <HEADER attr1="one" attr2="two" /> 
   <Table filename="12345.pdf"> 
      <left> 
         <details> 
            <item/> 
            <item/> 
         </details> 
      </left> 
      <right> 
         <details> 
            <item/> 
            <item/> 
         </details> 
      </right> 
   </Table> 
</Report> 

在尝试查询xml文档中的元素和属性时,我遇到了一个奇怪的问题,其中命名空间位于xml中。

当我尝试查询文档以获取带有以下xpath查询的header元素时,我总是得到null结果

XDocument root = XDocument.Load(filePath);
var element = root.XPathSelectElement("/Report/HEADER");

这总是返回null但是当我从文档中删除命名空间时,查询返回exepcted元素。

当我得到一些令人沮丧的东西时,我出错了什么。

编辑:将xml更新为有效的xml

1 个答案:

答案 0 :(得分:2)

我个人会建议您没有使用XPath执行此操作,但如果您真的需要,则可以。这是一个简短但完整的程序,可以在我修复之后使用您的示例XML(目前它不是有效的XML ...请尝试下次提供工作示例):

using System;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

class Test
{
    static void Main()
    {
        var doc = XDocument.Load("test.xml");
        var manager = new XmlNamespaceManager(new NameTable());
        manager.AddNamespace("foo", "TemplateXXX");

        var query = doc.XPathSelectElement("/foo:Report/foo:HEADER", manager);
        Console.WriteLine(query);
    }
}

在普通的LINQ to XML查询中,您只需使用:

XNamespace ns = "TemplateXXX";
XElement header = doc.RootElement.Element(ns + "HEADER");

不需要命名空间管理器等。