2015-01-07 1 views
1

У меня есть XML, малая его часть выглядит следующим образом:Синтаксический XML с пространствами имен с использованием ElementTree в Python

<?xml version="1.0" ?> 
<i:insert xmlns:i="urn:com:xml:insert" xmlns="urn:com:xml:data"> 
    <data> 
    <image imageId="1"></image> 
    <content>Content</content> 
    </data> 
</i:insert> 

Когда я разобрать его с помощью ElementTree и сохранить его в файл я вижу следующее:

<ns0:insert xmlns:ns0="urn:com:xml:insert" xmlns:ns1="urn:com:xml:data"> 
    <ns1:data> 
    <ns1:image imageId="1"></ns1:image> 
    <ns1:content>Content</ns1:content> 
    </ns1:data> 
</ns0:insert> 

Почему это изменяет префиксы и помещает их повсюду? Использование minidom У меня нет такой проблемы. Он настроен? Документация для ElementTree очень плохая. Проблема в том, что я не могу найти ни одного узла после такого разбора, например image - не может найти его с пространством имен или без него, если я использую его как {namespace}image или просто image. Почему это? Любые предложения заслуживают высокой оценки.

Что я уже пробовал:

import xml.etree.ElementTree as ET 
tree = ET.parse('test.xml') 
root = tree.getroot() 
for a in root.findall('ns1:image'): 
    print a.attrib 

Это возвращает ошибку, а другой ничего не возвращает:

for a in root.findall('{urn:com:xml:data}image'): 
    print a.attrib 

Я также попытался сделать пространство имен, как это и использовать его:

namespaces = {'ns1': 'urn:com:xml:data'} 
for a in root.findall('ns1:image', namespaces): 
    print a.attrib 

Он ничего не возвращает. Что я делаю не так?

+0

Можете ли вы добавить код Python, который используется для анализа XML? –

ответ

1

Этот фрагмент из вашего вопроса,

for a in root.findall('{urn:com:xml:data}image'): 
    print a.attrib 

не выводит ничего, потому что это выглядит только для прямых {urn:com:xml:data}image детей корня дерева.

Это слегка измененный код,

for a in root.findall('.//{urn:com:xml:data}image'): 
    print a.attrib 

напечатает {'imageId': '1'}, поскольку он использует .//, который выбирает соответствующие подэлементы на всех уровнях.

Код: https://docs.python.org/2/library/xml.etree.elementtree.html#supported-xpath-syntax.


Это немного раздражает, что ElementTree не только сохранить исходные префиксы пространства имен по умолчанию, но имейте в виду, что это не префиксы, что дело в любом случае. Функция register_namespace() может использоваться для установки желаемого префикса, когда сериализует XML. Функция не влияет на разбор или поиск.

0

Из того, что я собираюсь, это как-то связано с распознаванием пространства имен в ET.

здесь http://effbot.org/zone/element-namespaces.htm

При сохранении дерева элементов в XML, стандартный элемент сериализатору создает уникальные префиксы для всех URI: S, которые появляются в дереве. Префиксы обычно имеют форму «ns», за которой следует число. Например, вышеупомянутые элементы могут быть сериализованы с префиксом ns0 для «http://www.w3.org/1999/xhtml» и ns1 для «http://effbot.org/namespace/letters».

Если вы хотите использовать определенные префиксы, вы можете добавлять сопоставления префикса/uri в глобальную таблицу в модуле ElementTree. В 1.3 и более поздних версиях вы делаете это, вызывая функцию register_namespace. В более ранних версиях, вы можете получить доступ к внутренней таблицы непосредственно:

ElementTree 1,3

ET.register_namespace (префикс, Ури)

ElementTree 1,2 (Python 2.5)

ET._namespace_map [URI] = префикс

Обратите внимание на порядок аргументов; функция сначала берет префикс, а исходный словарь отображает от URI: s до префиксов.

+0

Я уже прочитал его и попробовал эту регистрацию пространства имен, но это не помогло. – tinySandy