首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用xml.etree解析XML值

使用xml.etree解析XML值
EN

Stack Overflow用户
提问于 2017-01-07 02:24:35
回答 3查看 70关注 0票数 1

这可能是一个非常简单的问题--但我是一名python/xml新手,似乎找不到适合我的答案。

我正在尝试解析XML值,并从xml响应中解析,如下所示

代码语言:javascript
复制
#!/usr/bin/python3
from xml.etree import cElementTree as ET
xmlstr = """<?xml version="1.0" encoding="utf-8"?>
<biwsXML_response type="find">
 <clientdata>
  <message></message>
  <query>jurnamn:Acme Ltd</query>
  <wpquery></wpquery>
  <wpfilter></wpfilter>
 </clientdata> 
 <records total="1">
  <record nr="1">
   <nummer>9990874474</nummer>
   <orgnr>9990874474</orgnr>
   <jurnamn>Acme1 Ltd</jurnamn>
   <ba_postort>T&#228;by</ba_postort>
   <abv_ugrupp></abv_ugrupp>
  </record>
  <record nr="2">
   <nummer>9890874474</nummer>
   <orgnr>9890874474</orgnr>
   <jurnamn>Acme2 Ltd</jurnamn>
   <ba_postort>T&#228;by</ba_postort>
   <abv_ugrupp></abv_ugrupp>
  </record>
 </records>
</biwsXML_response>
"""
biwsXML_response = ET.fromstring(xmlstr)
for records in list(biwsXML_response):
    orgnr = records.find('orgnr').text
    jurnamn = records.find('jurnamn').text
    print('orgnr: %s; jurnamn: %s' % (orgnr, jurnamn))

当我测试时,我得到了以下错误。

代码语言:javascript
复制
Traceback (most recent call last):
  File "read_xml_tst2.py", line 31, in <module>
    orgnr = records.find('orgnr').text
AttributeError: 'NoneType' object has no attribute 'text'

我知道我找不到'NoneType‘的值,但我不明白错误是什么。谢谢你的帮助。

EN

回答 3

Stack Overflow用户

发布于 2017-01-07 02:35:21

问题是,您必须在XML树中进一步深入。要进入orgnr,必须先进入records,然后进入record

这应该会对你有所帮助:

代码语言:javascript
复制
for record in biwsXML_response.find('records').findall('record'):
    orgnr = record.find('orgnr').text
    jurnamn = record.find('jurnamn').text
    print('orgnr: %s; jurnamn: %s' % (orgnr, jurnamn))
票数 1
EN

Stack Overflow用户

发布于 2017-01-07 02:41:40

迭代记录将查看<clientdata><records>元素。

然后,您将在下一层中搜索这些元素中的每一个元素,以查找具有标记orgnr的元素。这个标签在clientdata中根本不存在,在records中有2层。因此这两个函数都返回None

.find方法确实支持XPath表达式,您需要使用它来进行更深层次的搜索。

代码语言:javascript
复制
orgnr = biwsXML_response.find('.//orgnr').text
jurnamn = biwsXML_response.find('.//jurnamn').text

现在请记住,.find只返回找到的第一个元素,而不是所有匹配的元素。为此,您需要使用.findall.iterfind

票数 0
EN

Stack Overflow用户

发布于 2017-01-07 02:42:17

你不能这么做

代码语言:javascript
复制
records.find('orgnr').text

...well,你可以,但这是一个等待发生的运行时错误。不能保证.find()会返回一些有用的东西,所以您不能编写忽略这一事实的代码。

在本例中,错误是在代码处理clientdata元素时发生的。

任一

  • records.find('orgnr')存储在一个变量中,并在您尝试进一步访问它之前检查它是否为None,或者
  • 使用.findall()和循环,以便在未找到任何内容时不执行循环体,或者
  • 创建一个小辅助函数来获取元素的文本

除此之外,.find().findall()都可以与XPath一起工作。从一开始就搜索特定元素可能会更好。

以下是所有三个建议的组合:

代码语言:javascript
复制
biwsXML_response = ET.fromstring(xmlstr)

def get_text(context_element, xpath, default=''):
    element = context_element.find(xpath)
    return element.text if element else default

for record in biwsXML_response.findall('./records/record'):
    orgnr = get_text(record, './orgnr', 'N/A')
    jurnamn = get_text(record, './jurnamn', 'N/A')

    print('orgnr: %s; jurnamn: %s' % (orgnr, jurnamn))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41511939

复制
相关文章

相似问题

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