XPath和XML:多个名称空间

时间:2011-02-25 22:43:00

标签: xpath xml-namespaces

所以我有一个看起来像

的文件
<a xmlns="uri1" xmlns:pre2="uri2">
 <b xmlns:pre3="uri3">
   <pre3:c>
     <stuff></stuff>
     <goes></goes>
     <here></here>
   </pre3:c>
   <pre3:d xmlns="uri4">
     <under></under>
     <the></the>
     <tree></tree>
   </pre3:d>
  </b>
</a>

我想要一个xpath表达式,它会让我<under>

这有一个urri4的namespaceURI。

现在我的表情看起来像是:

//ns:a/ns:b/pre3:d/pre4:under

我有命名空间管理器为默认命名空间添加'ns'(在本例中为uri1),我分别用u2,uri3和uri4定义了pre2,pre3和pre4。

我收到错误“表达式必须评估为节点集。”

我知道该节点存在。我知道在我的xpath中pre4:under之前的所有内容都能正常工作,因为我在文档的其余部分中使用它没有任何问题。这是造成错误的额外pre4:under,我不确定原因。

有什么想法吗?

感谢。

解决:

感谢大家坚持认为这是正确的 - 确实如此。但是......在我的代码中,我将“pre4”改为“64”(变量),它不喜欢前缀的整数。将其更改为“d”+ myintvariable。

2 个答案:

答案 0 :(得分:3)

我的猜测是,您用于导航XML的实现可能存在错误。使用SketchPath,以下XPath成功导航到节点:

/def:a/def:b/pre3:d/def2:under

您可以尝试为XPath中的命名空间指定不同的前缀吗?否则,如果性能不是真正的问题,并且它是一个独特的节点,您可以尝试//under

答案 1 :(得分:0)

您的代码中存在错误,您尚未向我们展示

此C#控制台应用程序:

using System;
using System.Xml;


namespace Namespaces
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(
                @"<a xmlns='uri1' xmlns:pre2='uri2'>
                    <b xmlns:pre3='uri3'>
                        <pre3:c>
                            <stuff></stuff>
                            <goes></goes>
                            <here></here>
                        </pre3:c>
                        <pre3:d xmlns='uri4'>
                            <under></under>
                            <the></the>
                            <tree></tree>
                        </pre3:d>
                    </b>
                </a>"                
                       );
            XmlNamespaceManager nsman = 
                new XmlNamespaceManager(new NameTable());
            nsman.AddNamespace("ns", "uri1");
            nsman.AddNamespace("pre2", "uri2");
            nsman.AddNamespace("pre3", "uri3");
            nsman.AddNamespace("pre4", "uri4");

            Console.WriteLine(
                doc.SelectSingleNode("/")
                  .SelectNodes("//ns:a/ns:b/pre3:d/pre4:under",

                                nsman)[0].OuterXml
                              );
        }
    }
}

执行时,会生成所需的正确结果:

<under xmlns="uri4"></under>