Как получить пространства имен в файлах XML с помощью Xpath

У меня есть XML-файл, который начинается следующим образом:

 

Мне придется открыть много этих файлов. Каждое из них имеет другое пространство имен, но будет иметь только одно пространство имен за раз (я никогда не найду два пространства имен, определенные в одном XML-файле).

Используя XPath, я хотел бы иметь автоматический способ добавления данного пространства имен в диспетчер пространства имен. До сих пор я мог получить только пространство имен, анализируя XML-файл, но у меня есть экземпляр XPathNavigator, и у него должен быть хороший и чистый способ получить пространства имен, верно?

— ИЛИ —

Учитывая, что у меня только одно пространство имен, каким-то образом XPath использует единственную, которая присутствует в xml, что позволяет избежать загромождения кода, всегда добавляя пространство имен.

Есть несколько методов, которые вы можете попробовать; который вы используете, будет зависеть именно от того, какую информацию вам нужно получить из документа, насколько строго вы хотите быть и насколько совместима реализация XPath, которую вы используете.

Один из способов получить URI пространства имен, связанный с определенным префиксом, – использовать namespace:: axis. Это даст вам узел пространства имен, имя которого является префиксом и значением которого является URI пространства имен. Например, вы можете получить URI пространства имен по умолчанию в элементе документа, используя путь:

 /*/namespace::*[name()=''] 

Возможно, вы сможете использовать это для создания ассоциаций пространств имен для своего XPathNavigator. Однако следует предупредить, что namespace:: axis является одним из тех углов XPath 1.0, которые не всегда реализованы.

Второй способ получения этого URI пространства имен – использовать функцию namespace-uri() в элементе документа (который, как вы сказали, всегда будет в этом пространстве имен). Выражение:

 namespace-uri(/*) 

предоставит вам это пространство имен.

Альтернативой было бы забыть об ассоциировании префикса с этим пространством имен и просто сделать свой путь без пространства имен. Вы можете сделать это, используя функцию local-name() когда вам нужно обратиться к элементу, пространство имен которого вы не знаете. Например:

 //*[local-name() = 'Element'] 

Вы можете пойти еще на один шаг и протестировать URI пространства имен элемента по отношению к одному из элементов документа, если вы действительно захотите:

 //*[local-name() = 'Element' and namespace-uri() = namespace-uri(/*)] 

Последний вариант, учитывая, что пространство имен, кажется, ничего не значит для вас, было бы запустить ваш XML через фильтр, который удаляет пространства имен. Тогда вам не придется беспокоиться о них в своем XPath. Самый простой способ сделать это – просто удалить атрибут xmlns с регулярным выражением, но вы могли бы сделать что-то более сложное, если бы вам нужно было делать другие приемы в одно и то же время.

Это 40-строчное преобразование xslt предоставляет всю полезную информацию об пространствах имен в данном XML-документе :

                       

При применении к следующему XML-документу:

            

получается желаемый результат:

                

К сожалению, у XPath нет понятия «пространство имен по умолчанию». Вам необходимо зарегистрировать пространства имен с префиксами с контекстом XPath, а затем использовать эти префиксы в выражениях XPath. Это означает, что для очень сложного xpath, но это основной недостаток XPath 1. Очевидно, XPath 2 рассмотрит это, но это бесполезно для вас прямо сейчас.

Я предлагаю вам программно изучить ваш XML-документ для пространства имен, связать это пространство имен с префиксом в контексте XPath, а затем использовать префикс в выражениях xpath.

  • Поддерживает ли C # проектное пространство имён по умолчанию, как VB.NET?
  • как игнорировать пространства имен с XPath
  • Почему «использование пространства имен X» не допускается внутри уровня classа / структуры?
  • XPath с пространством имен в Java
  • Использование std-пространства имен
  • имя не существует в пространстве имен clr-namespace
  • Пространства имен в C
  • Как правильно использовать пространства имен в C ++?
  • Без имени / анонимных пространств имен или статических функций
  • XML По умолчанию пространства имен для имен неквалифицированных атрибутов?
  • Какова ближайшая вещь, которую MATLAB имеет для пространств имен?
  • Давайте будем гением компьютера.