Отбросить все пространства имен в lxml? - PullRequest
4 голосов
/ 16 февраля 2012

Я работаю с некоторыми API данных Google, используя библиотеку lxml в python. Пространства имен - огромная проблема. Для большей части работы, которую я делаю (главным образом, xpath), было бы просто игнорировать их.

Есть ли простой способ игнорировать пространства имен xml в python / lxml?

спасибо!

Ответы [ 2 ]

1 голос
/ 27 июля 2013

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

Контекст: в моем приложении я получаю XML-представления потоков ответов SOAP, но яне заинтересованы в строительстве объектов на стороне клиента;Меня интересуют только сами представления XML.Более того, меня не интересует какая-либо вещь пространства имен, которая только делает вещи более сложными, чем они должны быть, для моих целей.Итак, я просто удаляю пространства имен из элементов и удаляю все атрибуты, которые содержат пространства имен.

def dropns(root):
    for elem in root.iter():
        parts = elem.tag.split(':')
        if len(parts) > 1:
            elem.tag = parts[-1]
        entries = []
        for attrib in elem.attrib:
            if attrib.find(':') > -1:
                entries.append(attrib)
        for entry in entries:
            del elem.attrib[entry]

# Test case
name = '~/tmp/mantisbt/test.xml'
f = open(name, 'rb')
import lxml.etree as etree
parser = etree.XMLParser(ns_clean=True, recover=True)
root = etree.parse(f, parser=parser)
print('=====================================================================')
print etree.tostring(root, pretty_print = True)
print('=====================================================================')
dropns(root)
print etree.tostring(root, pretty_print = True)
print('=====================================================================')

, который печатает:

=====================================================================
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <ns1:mc_issue_getResponse>
      <return xsi:type="tns:IssueData">
        <id xsi:type="xsd:integer">356</id>
        <view_state xsi:type="tns:ObjectRef">
          <id xsi:type="xsd:integer">10</id>
          <name xsi:type="xsd:string">public</name>
        </view_state>
    </return>
  </ns1:mc_issue_getResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
=====================================================================
<Envelope>
  <Body>
    <mc_issue_getResponse>
      <return>
        <id>356</id>
        <view_state>
          <id>10</id>
          <name>public</name>
        </view_state>
    </return>
  </mc_issue_getResponse>
</Body>
</Envelope>
=====================================================================
0 голосов
/ 09 августа 2012

В lxml some_element.tag это строка типа {namespace-uri}local-name, если есть пространство имен, просто local-name в противном случае. Помните, что это не строковое значение на неэлементных узлах (например, комментарии).

Попробуйте это:

for node in some_tree.iter():
    startswith = getattr(node 'startswith', None)
    if startswith and startswith('{'):
        node.tag = node.tag.rsplit('}', 1)[-1]

В Python 2.x тег может быть либо байтовой строкой ASCII, либо строкой Unicode. Существование метода startsith для любого из них.

...