python-3.x - XML 解析错误 AttributeError:“NoneType”对象没有属性“文本”
问题描述
我的问题可能有一个简单的解决方案,但我对 python3 很陌生,所以请放轻松;)
我有一个简单的脚本正在运行,它已经使用此代码成功地解析了 xml 文件中的信息
import xml.etree.ElementTree as ET
root = ET.fromstring(my_xml_file)
u = root.find(".//name").text.rstrip()
print("Name: %s\n" % u)
我正在解析的 xml 看起来像这样
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/3.2/style/exchange.xsl"?>
<example:world-data xmlns="http://www.example.org" xmlns:ops="http://example.oorg" xmlns:xlink="http://www.w3.oorg/1999/xlink">
<exchange-documents>
<exchange-document system="acb.org" family-id="543672" country="US" doc-number="95962" kind="B2">
<bibliographic-data>
<name>SomeName</name>
...and so on... and ends like this
</exchange-document>
</exchange-documents>
</example:world-data>
(由于stackoverflow政策,链接被编辑)
按预期输出
SomeName
但是,如果我尝试使用相同的 python 命令从同一个 api 解析另一个 xml,我会得到这个错误代码
AttributeError: 'NoneType' object has no attribute 'text'
第二个 xml 文件看起来像这样
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/3.2/style/pub-ftxt-claims.xsl"?>
<ops:world-data xmlns="http://www.example.org/exchange" xmlns:example="http://example.org" xmlns:xlink="http://www.example.org/1999/xlink">
<ftxt:fulltext-documents xmlns="http://www.examp.org/fulltext" xmlns:ftxt="ww.example/fulltext">
<ftxt:fulltext-document system="example.org" fulltext-format="text-only">
<bibliographic-data>
<publication-reference data-format="docdb">
<document-id>
<country>EP</country>
<doc-number>10000</doc-number>
<kind>A</kind>
</document-id>
</publication-reference>
</bibliographic-data>
<claims lang="EN">
<claim>
<claim-text>1. Some text.</claim-text>
<claim-text>2. Some text.</claim-text>
<claim-text>2. Some text.</claim-text>
</claim>
</claims>
</ftxt:fulltext-document>
</ftxt:fulltext-documents>
</ops:world-data>
我又试了
root = ET.fromstring(usr_str)
u = root.find(".//claim-text").text.rstrip()
print("Abstract: %s\n" % u)
预期产出
1. Some text.
但它只打印上述错误消息。为什么我可以使用这些命令解析第一个 xml 而不是第二个?
非常感谢任何帮助。
编辑:Jack Fleeting 的代码在 python 控制台中工作,但不幸的是不在我的 PyCharm
from lxml import etree
root = etree.XML(my_xml.encode('ascii'))
root2 = etree.XML(my_xml2.encode('ascii'))
root.xpath('//*[local-name()="name"]/text()')
root2.xpath('//*[local-name()="claim-text"]/text()')
这可能是我的 PyCharm 中的一个错误吗?我第一次提到的代码片段仍然打印出正确的名称结果...
编辑:原来我不得不使用强制输出
a = root3.xpath('//*[local-name()="claim-text"]/text()')
print(a, flush=True)
解决方案
在我们找到可能的解决方案之前,这里有几个问题。一,您提供的第一个 xml 片段无效(例如,<bibliographic-data>
未关闭)。我意识到这只是一个片段,但由于这是我们必须使用的,我修改了下面的片段来解决这个问题。二,两个片段都有带有未绑定(未使用)前缀的 xmlns 声明(example:world-data
在第一个和ops:world-data
第二个中)。我也必须删除这些前缀,其余的才能正常工作。
鉴于这些修改,使用 lxml 库应该适合您。
第一个修改片段:
my_xml = """<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/3.2/style/exchange.xsl"?>
<world-data xmlns="http://www.example.org" xmlns:ops="http://example.oorg" xmlns:xlink="http://www.w3.oorg/1999/xlink">
<exchange-documents>
<exchange-document system="acb.org" family-id="543672" country="US" doc-number="95962" kind="B2">
<bibliographic-data>
<name>SomeName</name>
...and so on... and ends like this
</bibliographic-data>
</exchange-document>
</exchange-documents>
</world-data>"""
和:
my_xml2 = """<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/3.2/style/pub-ftxt-claims.xsl"?>
<world-data xmlns="http://www.example.org/exchange" xmlns:example="http://example.org" xmlns:xlink="http://www.example.org/1999/xlink">
<ftxt:fulltext-documents xmlns="http://www.examp.org/fulltext" xmlns:ftxt="ww.example/fulltext">
<ftxt:fulltext-document system="example.org" fulltext-format="text-only">
<bibliographic-data>
<publication-reference data-format="docdb">
<document-id>
<country>EP</country>
<doc-number>10000</doc-number>
<kind>A</kind>
</document-id>
</publication-reference>
</bibliographic-data>
<claims lang="EN">
<claim>
<claim-text>1. Some text.</claim-text>
<claim-text>2. Some text.</claim-text>
<claim-text>3. Some text.</claim-text>
</claim>
</claims>
</ftxt:fulltext-document>
</ftxt:fulltext-documents>
</world-data>"""
现在开始工作:
from lxml import etree
root = etree.XML(my_xml.encode('ascii'))
root2 = etree.XML(my_xml2.encode('ascii'))
root.xpath('//*[local-name()="name"]/text()')
输出:
['某个名字']
root2.xpath('//*[local-name()="claim-text"]/text()')
输出:
['1。一些文字。','2。一些文字。','3。一些文字。']
推荐阅读
- curl - 无法接收 POST 请求 Asp.net core 2.2
- javascript - 显示带有动态数据的 Facebook 分享按钮
- jquery - 以模态形式Jquery显示来自MYSQL的特殊字符?
- javascript - 为什么 CSSOM 构建不等待 Javascript 执行?
- regex - 如果字符串的部分部分存在于另一列中,则匹配,例如,如果 AUD 存在于一列中,则突出显示 AUDUSD
- android - SearchView 在 Android 中不起作用。为什么这样?
- python - VScode:使用任务自动将python文件转换为Jupyter笔记本
- c++ - 未报告的错误 VS 2015:十六进制字符说明符
- xml - 如何在 xslt 中添加计时器
- ios - 如何在几秒钟内计算 1000 分中的分数(双倍)