XPath和XML:多名称空间

XPath和XML:多名称空间,xpath,xml-namespaces,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">

所以我有一个文件看起来像

<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>
在本例中,我让名称空间管理器为默认名称空间uri1添加“ns”,并分别为uri2、uri3和uri4定义了pre2、pre3和pre4

我得到的错误表达式必须计算为一个节点集

我知道节点存在。我知道xpath中的pre4:under之前的所有内容都可以正常工作,因为我在文档的其余部分使用它时没有任何问题。这是额外的pre4:under导致的错误,我不知道为什么

有什么想法吗

谢谢

决议:


谢谢大家坚持认为这是正确的。但是在我的代码中,pre4是一个变量,它不喜欢用整数作为前缀。将其更改为d+myintvariable有效。

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

/def:a/def:b/pre3:d/def2:under
能否尝试为XPath中的名称空间指定不同的前缀?否则,如果性能不是一个真正的问题,并且它是一个唯一的节点,您可以尝试//在

下,您的代码中有一个错误,您没有向我们显示该错误

此C控制台应用程序:

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


按照您描述的方式注册名称空间后,该表达式应选择所需的下元素。我认为您需要提供更多的上下文信息。如果这是一个愚蠢的问题,很抱歉,但我在任何地方都看不到pre4命名空间的定义。这仅仅是因为打字错误,还是这就是问题所在?我想不出我还能给你什么。Jon,在调用表达式之前,我使用nsmgr.AddNamespacepre4,navigator.NamespaceURI。是的,这是正确的。也许问题是我不应该定义第二个默认名称空间?好问题,+1。请参阅我的答案,了解一个完整而简短的C应用程序,它成功地使用了您问题中的XPath表达式并生成了正确的结果。不,遗憾的是,根本不能保证它是唯一的节点。我将用完整的文档和相关的表达式来尝试sketchpath,看看会发生什么。
/def:a/def:b/pre3:d/def2:under
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>