Изменить префикс пространства имен с помощью ElementTree в Python - PullRequest
18 голосов
/ 09 августа 2009

По умолчанию, когда вы вызываете ElementTree.parse (someXMLfile), библиотека Python ElementTree ставит перед каждым анализируемым узлом префикс своего URI пространства имен в нотации Кларка:

    {http://example.org/namespace/spec}mynode

Это делает доступ к определенным узлам по имени огромной болью позже в коде.

Я прочитал документы по ElementTree и пространствам имен, и похоже, что функция iterparse() должна позволить мне изменить способ, которым парсер префиксирует пространства имен, но на самом деле я не могу заставить его изменить префикс. Кажется, что это может произойти в фоновом режиме до того, как событие ns-start даже сработает, как в этом примере:

for event, elem in iterparse(source):
    if event == "start-ns":
        namespaces.append(elem)
    elif event == "end-ns":
        namespaces.pop()
    else:
        ...

Как мне сделать так, чтобы оно изменило поведение префикса и что нужно возвращать после завершения функции?

Ответы [ 2 ]

6 голосов
/ 10 августа 2009

Вам не нужно специально использовать iterparse. Вместо этого следующий скрипт:

from cStringIO import StringIO
import xml.etree.ElementTree as ET

NS_MAP = {
    'http://www.red-dove.com/ns/abc' : 'rdc',
    'http://www.adobe.com/2006/mxml' : 'mx',
    'http://www.red-dove.com/ns/def' : 'oth',
}

DATA = '''<?xml version="1.0" encoding="utf-8"?>
<rdc:container xmlns:mx="http://www.adobe.com/2006/mxml"
                 xmlns:rdc="http://www.red-dove.com/ns/abc"
                 xmlns:oth="http://www.red-dove.com/ns/def">
  <mx:Style>
    <oth:style1/>
  </mx:Style>
  <mx:Style>
    <oth:style2/>
  </mx:Style>
  <mx:Style>
    <oth:style3/>
  </mx:Style>
</rdc:container>'''

tree = ET.parse(StringIO(DATA))
some_node = tree.getroot().getchildren()[1]
print ET.fixtag(some_node.tag, NS_MAP)
some_node = some_node.getchildren()[0]
print ET.fixtag(some_node.tag, NS_MAP)

производит

('mx:Style', None)
('oth:style2', None)

Показывает, как вы можете получить доступ к полным именам тегов отдельных узлов в разобранном дереве Вы должны быть в состоянии приспособить это к вашим конкретным потребностям.

2 голосов
/ 15 декабря 2009

xml.etree.ElementTree, похоже, не имеет метки, ну, не в соответствии с документацией. Однако я посмотрел на некоторый исходный код для fixtag, и вы делаете:

import xml.etree.ElementTree as ET

for event, elem in ET.iterparse(inFile, events=("start", "end")):
    namespace, looktag = string.split(elem.tag[1:], "}", 1)

У вас есть строка тега в looktag, подходящая для поиска. Пространство имен находится в пространстве имен.

...