2016-07-26 3 views
1

Я работаю с довольно сложной XML, как это:LXML работы с пространствами имен

<?xml version="1.0" encoding="UTF-8"?> 
<!-- ***** Configuration Data exported at 20160623T110335 ***** --> 
<impex:ExportData xmlns:impex="urn:swift:saa:xsd:impex"> 

<!-- *** Exported Data for Operator *** --> 
<OperatorData xmlns="urn:swift:saa:xsd:impex:operator"> 

<ns2:OperatorDefinition xmlns="urn:swift:saa:xsd:operatorprofile" xmlns:ns2="urn:swift:saa:xsd:impex:operator" xmlns:ns3="urn:swift:saa:xsd:unit" xmlns:ns4="urn:swift:saa:xsd:licenseddestination" xmlns:ns5="urn:swift:saa:xsd:operator" xmlns:ns6="urn:swift:saa:xsd:authenticationservergroup"> 
    <ns2:Operator> 
     <ns5:Identifier> 
      <ns5:Name>jdoe</ns5:Name> 
     </ns5:Identifier> 
     <ns5:Description>John Doe</ns5:Description> 
     <ns5:OperatorType>HUMAN</ns5:OperatorType> 
     <ns5:AuthenticationType>LDAP</ns5:AuthenticationType> 
     <ns5:AuthenticationServerGroup> 
      <ns6:Type>LDAP</ns6:Type> 
      <ns6:Name>LDAP_GROUP1</ns6:Name> 
     </ns5:AuthenticationServerGroup> 
     <ns5:LdapUserId>jdoe</ns5:LdapUserId> 
     <ns5:Profile> 
      <Name>DEV Users</Name> 
     </ns5:Profile> 
     <ns5:Unit> 
      <ns3:Name>None</ns3:Name> 
     </ns5:Unit> 
    </ns2:Operator> 
</ns2:OperatorDefinition> 

</OperatorData> 

</impex:ExportData> 

В XML существуют многочисленные <ns2:OperatorDefinition> элементы, как один я включил. Мне трудно понять, как вытащить что-то вроде <ns5:Description>, используя lxml. Все примеры для пространств имен, которые я нахожу, не являются сложными.

Я пытаюсь просто найти теги делают что-то вроде этого -

from lxml import etree 
doc = etree.parse('c:/robin/Operators_out.xml') 

r = doc.xpath('/x:OperatorData/ns2:OperatorDefinition', namespaces={'x': 'urn:swift:saa:xsd:impex:operator'}) 
print len(r) 
print r[0].text 
print r[0].tag 

я Undefined namespace prefix.

+1

Вы получаете «Неопределенный префикс пространства имен», потому что вы не включили определение префикса 'ns2' в словарь« namespaces ». – mzjn

ответ

1

Вам не нужно пространств имен для вашего сценария использования, remove them сделать разбор проще:

from lxml import etree, objectify 

tree = etree.parse("input.xml") 
root = tree.getroot() 

# remove namespaces ---- 
for elem in root.getiterator(): 
    if not hasattr(elem.tag, 'find'): continue 
    i = elem.tag.find('}') 
    if i >= 0: 
     elem.tag = elem.tag[i+1:] 

objectify.deannotate(root, cleanup_namespaces=True) 
# ---- 

name = root.findtext(".//OperatorDefinition/Operator/Identifier/Name") 
print(name) 

Печать jdoe.

+0

Это работает для единственного пользователя. Я пытаюсь понять, как его зацикливать, если в них есть несколько 'OperatorDefinitions' с теми же тегами? то есть. Я хочу вернуть 'jdoe',' asmith' и т. Д. – whoisearth

+0

@whoisearth в порядке, выполните '.// OperatorDefinition/Operator/Identifier/Name/text()'. – alecxe

+0

@alecse Я закончил это, и он работает - 'для elem in tree.iterfind ('.// ​​OperatorDefinition'): print elem.findtext (" .// Operator/Identifier/Name ")' – whoisearth

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