首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用lxml解析具有多个名称空间的xml

使用lxml解析具有多个名称空间的xml
EN

Stack Overflow用户
提问于 2015-07-23 05:19:17
回答 1查看 625关注 0票数 3

我从一个SOAP api中提取xml,如下所示:

代码语言:javascript
复制
<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ae="urn:sbmappservices72" xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:diag="urn:SerenaDiagnostics" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
    <ae:GetItemsByQueryResponse>
      <ae:return>
        <ae:item>
          <ae:id xsi:type="ae:ItemIdentifier">
            <ae:displayName/>
            <ae:id>10</ae:id>
            <ae:uuid>a9b91034-8f4d-4043-b9b6-517ba4ed3a33</ae:uuid>
            <ae:tableId>1541</ae:tableId>
            <ae:tableIdItemId>1541:10</ae:tableIdItemId>
            <ae:issueId/>
          </ae:id>

我无论如何也不能用findall来拉出像tableId这样的东西。大多数关于使用lxml进行解析的教程都不包含名称空间,但the one at lxml.de包含名称空间,我一直在尝试遵循它。

根据他们的教程,你应该创建一个名称空间的字典,我已经这样做了:

代码语言:javascript
复制
r = tree.xpath('/e:SOAP-ENV/s:ae', 
        namespaces={'e': 'http://schemas.xmlsoap.org/soap/envelope/',
                    's': 'urn:sbmappservices72'})

但这似乎不起作用,因为当我尝试获取r的len时,它返回为0:

代码语言:javascript
复制
print 'length: ' + str(len(r)) #<---- always equals 0

因为第二个名称空间的URI是"urn:",所以我也尝试使用wsdl的真实URL,但得到的结果是相同的。

我是不是明显漏掉了什么?我只需要能够拉取类似于tableIdItemId的值。

任何帮助都将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2015-07-23 08:44:08

您的XPath不能正确地对应于XML结构。请尝试这种方式:

代码语言:javascript
复制
r = tree.xpath('/e:Envelope/e:Body/s:GetItemsByQueryResponse/s:return/s:item/s:id/s:tableId', 
        namespaces={'e': 'http://schemas.xmlsoap.org/soap/envelope/',
                    's': 'urn:sbmappservices72'})

对于小型XML,您可能希望使用//而不是/来简化表达式,例如:

代码语言:javascript
复制
r = tree.xpath('/e:Envelope/e:Body//s:tableId', 
        namespaces={'e': 'http://schemas.xmlsoap.org/soap/envelope/',
                    's': 'urn:sbmappservices72'})

无论tableId嵌套在Body中有多深,/e:Body//s:tableId都会找到它。但是,请注意,//肯定比/慢,特别是在应用于大型XML时。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31574173

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档