2014-11-04 5 views
2

xmltodict преобразует XML в словарь Python. Он поддерживает пространства имен. Я могу следовать примеру на главной странице и успешно удалить пространство имен. Однако я не могу удалить пространство имен из моего XML и не могу определить, почему? Вот мой XML:Удалить пространство имен с помощью xmltodict в Python

<?xml version="1.0" encoding="UTF-8"?> 
<status xmlns:mystatus="http://localhost/mystatus"> 
<section1 
    mystatus:field1="data1" 
    mystatus:field2="data2" /> 
<section2 
    mystatus:lineA="outputA" 
    mystatus:lineB="outputB" /> 
</status> 

И с помощью:

xmltodict.parse(xml,process_namespaces=True,namespaces={'http://localhost/mystatus':None}) 

я получаю:

OrderedDict([(u'status', OrderedDict([(u'section1', OrderedDict([(u'@http://localhost/mystatus:field1', u'data1'), (u'@http://localhost/mystatus:field2', u'data2')])), (u'section2', OrderedDict([(u'@http://localhost/mystatus:lineA', u'outputA'), (u'@http://localhost/mystatus:lineB', u'outputB')]))]))]) 

вместо:

OrderedDict([(u'status', OrderedDict([(u'section1', OrderedDict([(u'field1', u'data1'), (u'field2', u'data2')])), (u'section2', OrderedDict([(u'lineA', u'outputA'), (u'@lineB', u'outputB')]))]))]) 

Могу ли я сделать некоторую простую ошибку, или есть что-то о моем XML, который предотвращает process_na mespace от правильной работы?

ответ

2

xmltodict основан на expat, так что пространство имен должно применяться к имени класса, имена не приписывают:

<?xml version="1.0" encoding="UTF-8"?> 
<status xmlns:mystatus="http://localhost/mystatus"> 
    <mystatus:section1 field1="data1" field2="data2" /> 
    <mystatus:section2 lineA="outputA" lineB="outputB" /> 
</status> 

При проанализирован с:

foo = xmltodict.parse(xml, 
         process_namespaces=True, 
         namespaces={'http://localhost/mystatus':None}) 

выходов:

OrderedDict([(u'status', OrderedDict([(u'section1', OrderedDict([(u'@field1', u'data1'), (u'@field2', u'data2')])), (u'section2', OrderedDict([(u'@lineA', u'outputA'), (u'@lineB', u'outputB')]))]))]) 

Доступ к нему легко:

# Get attribute 'lineA' from class 'section2' from class 'status' 
>>> foo.get('status').get('section2').get('@lineA') 
u'outputA' 

Пространства имен атрибутов требуются только в том случае, если у вас есть несколько атрибутов с одним и тем же именем (например, несколько идентификаторов или несколько цен и т. д.), и в этом случае я не смог получить expat или xmltodict, чтобы проанализировать его правильно. Тем не менее, YMMV.

+0

Я не контролирую источник XML, так ли это значит, что мне не повезло, что xmltodict работает так, как мне хотелось бы? Если да, можете ли вы порекомендовать лучший подход, начиная с показанного мной XML? – proximous

+0

Звучит так. Мне не хватает эксперта по пространствам имен, чтобы сказать наверняка. В конечном счете, вы всегда можете извлечь ключи с полным пространством имен или написать некоторую функцию, которая удаляет префикс http: // */из ключей в dict, после разбора дерева xmltodict. – VooDooNOFX

+0

Спасибо. Поскольку мой XML начинается как строка, я просто извлечу его из строки перед разбором. Не идеально, но теперь, когда я понимаю, почему это не работает, изменение его с помощью строкового манипулирования не так уж плохо. :) – proximous

Смежные вопросы