XPath и XML: несколько пространств имен - PullRequest
4 голосов
/ 26 февраля 2011

Итак, у меня есть документ, который выглядит как

<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>.

Это имеет namespaceURI uri4.

Прямо сейчас мое выражение выглядит так:

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

У меня есть диспетчер пространства имен, добавляющий 'ns' для пространства имен по умолчанию (в данном случае uri1), и он определен с pre2, pre3 и pre4 для uri2, uri3 и uri4 соответственно.

Я получаю сообщение об ошибке «Выражение должно соответствовать набору узлов».

Я знаю, что узел существует. Я знаю, что все, вплоть до pre4:under в моем xpath, работает нормально, так как я использую его в остальной части документа без проблем. Это дополнительный pre4:under, который вызывает ошибку, и я не уверен, почему.

Есть идеи?

Спасибо.

Разрешение:

Спасибо всем за вашу настойчивость, что это правильно - так и было. Но ... в моем коде у меня было "pre4" как "64" (переменная), и ему не нравилось целое число для префикса. Изменение его на «d» + myintvariable сработало.

Ответы [ 2 ]

3 голосов
/ 26 февраля 2011

Я предполагаю, что может быть ошибка в реализации, которую вы используете для навигации по XML. Используя SketchPath , следующий XPath успешно перешел на узел:

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

Не могли бы вы попытаться указать разные префиксы для пространств имен в XPath? В противном случае, если производительность на самом деле не является проблемой, и это уникальный узел, вы можете просто попробовать //under

0 голосов
/ 26 февраля 2011

В вашем коде есть ошибка, которую вы не показали нам .

Это консольное приложение 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>
...