Python: ElementTree, получить строку пространства имен элемента

Этот XML файл имеет имя example.xml:

<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>14.0.0</modelVersion>
  <groupId>.com.foobar.flubber</groupId>
  <artifactId>uberportalconf</artifactId>
  <version>13-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>Environment for UberPortalConf</name>
  <description>This is the description</description>    
  <properties>
      <birduberportal.version>11</birduberportal.version>
      <promotiondevice.version>9</promotiondevice.version>
      <foobarportal.version>6</foobarportal.version>
      <eventuberdevice.version>2</eventuberdevice.version>
  </properties>
  <!-- A lot more here, but as it is irrelevant for the problem I have removed it -->
</project>

Если я загружу example.xml и проанализирую его с помощью ElementTree, я могу увидеть, что его пространство имен - http://maven.apache.org/POM/4.0.0.

>>> from xml.etree import ElementTree
>>> tree = ElementTree.parse('example.xml')
>>> print tree.getroot()
<Element '{http://maven.apache.org/POM/4.0.0}project' at 0x26ee0f0>

Я не нашел метод вызова, чтобы получить просто пространство имен из Element не прибегая к синтаксическому анализу str(an_element) элемента. Похоже, что должен быть лучший способ.

Ответ 3

Я не уверен, возможно ли это с помощью xml.etree, но вот как вы могли это сделать с помощью lxml.etree:

>>> from lxml import etree
>>> tree = etree.parse('example.xml')
>>> tree.xpath('namespace-uri(.)')
'http://maven.apache.org/POM/4.0.0'

Ответ 4

Без использования регулярных выражений:

>>> root
<Element '{http://www.google.com/schemas/sitemap/0.84}urlset' at 0x2f7cc10>

>>> root.tag.split('}')[0].strip('{')
'http://www.google.com/schemas/sitemap/0.84'

Ответ 5

Я думаю, будет легче взглянуть на атрибуты:

>>> root.attrib
{'{http://www.w3.org/2001/XMLSchema-instance}schemaLocation':
   'http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd'}

Ответ 6

lxml.xtree библиотеки lxml.xtree имеет словарь под названием nsmap, который показывает все пространство имен, которое используется в текущей области тега.

>>> item = tree.getroot().iter().next()
>>> item.nsmap
{'md': 'urn:oasis:names:tc:SAML:2.0:metadata'}

Ответ 7

Короткий ответ:

ElementTree._namspace_map[ElementTree._namspace_map.values().index('')]

но только если вы звонили

ElementTree.register_namespace(prefix,uri)

в ответ на каждое событие == "start-ns", полученное во время итерации через результат

ET.iterparse(...) 

и вы зарегистрировались для "start-ns"

Ответ на вопрос "что такое пространство имен по умолчанию?", Необходимо уточнить два момента:

(1) Спецификации XML говорят, что пространство имен по умолчанию не обязательно является глобальным по всему дереву, а пространство имен по умолчанию может быть повторно объявлено в любом элементе под root и наследуется вниз, пока не будет повторено повторное объявление другого пространства имен по умолчанию.

(2) Модуль ElementTree может (де-факто) обрабатывать XML-подобные документы, которые не имеют корневого пространства имен по умолчанию, -если они не используют пространство имен в любом месте документа. (* могут быть менее строгие условия, например, "если" и не обязательно "iff").

Вероятно, также стоит подумать: "Чего вы хотите?" Учтите, что XML файлы могут быть семантически эквивалентными, но синтаксически очень разными. Например, следующие три файла семантически эквивалентны, но у A.xml есть одно объявление пространства имен по умолчанию, B.xml имеет три, а C.xml - нет.

A.xml:
<a xlmns="http://A" xlmns:nsB0="http://B0" xlmns:nsB1="http://B1">
     <nsB0:b/>
     <nsB1:b/>
</a>

B.xml:
<a xlmns="http://A">
     <b xlmns="http://B0"/>
     <b xlmns="http://B1"/>
</a>

C.xml:
<{http://A}a>
     <{http://B0}b/>
     <{http://B1}b/>
</a>

Файл C.xml - это каноническое расширенное синтаксическое представление, представленное в функции поиска ElementTree.

Если вы уверены, что не будет конфликтов имен пространства, вы можете изменить теги элементов при разборе, как описано здесь: Модуль Python ElementTree: как игнорировать пространство имен XML файлов, чтобы найти соответствующий элемент при использовании метода "найти", "найти все"

Ответ 8

Объединив некоторые из приведенных выше ответов, я думаю, что самый короткий код

theroot = tree.getroot()
theroot.attrib[theroot.keys()[0]]