使用 cElementTree 解析 XML
Parsing XML with cElementTree
我的任务是将一些旧的 XML 解析代码重写为 Python,我偶然发现了 cElementTree
的乐趣,我喜欢它,因为我可以这样做这么多行。
我对 xpath
的经验水平不是那么广泛,这个问题更多的是关于进一步深入结构。
我在 test.xml
中有这个
<?xml version="1.0"?>
<ownershipDocument>
<issue>
<ic>0000030305</ic>
<iname>DUCOMM</iname>
<its>DCP</its>
</issue>
<ndt>
<ndtran>
<tc>
<tft>4</tft>
<tc>P</tc>
<esi>0</esi>
</tc>
</ndtran>
<ndtran>
<tc>
<tft>4</tft>
<tc>P</tc>
<esi>0</esi>
</tc>
</ndtran>
</ndt>
</ownershipDocument>
我在 Python 中写了这个脚本:
import xml.etree.cElementTree as ET
tree = ET.parse('test.xml')
root = tree.getroot()
print root.tag
print root.attrib
for child in root:
print(child.tag, child.attrib)
for issue in root.findall('issue'):
ic = issue.find('ic').text
iname= issue.find('iname').text
print(ic,iname)
这给了我:
ownershipDocument
{}
('issue', {})
('ndt', {})
('0000030305', 'DUCOMM')
这成功地让我在 "issue" 中获得了我需要的信息。
问题是我需要访问多个 "ndtran" 节点(在 "ndt" 节点中)。在解析时,我可以提取 "tft"、"tc" 和 "esi" 值作为组,但我需要遍历每个 "tc" 节点,提取 "tft"、"tc","esi" 个值,将它们插入数据库,然后移动到下一个 "tc" 节点并再次执行。
我试图用来遍历每一个的是这样的:
for tc in root.findall("./ndt/ndtran/tc"):
tft = tc.find('tft').text
tc = tc.find('tc').text
esi = tc.find('esi').text
print(tft,tc,esi)
这几乎让我到达那里(我认为)但它确实给了我一个错误。
esi = tc.find('esi').text
AttributeError: 'int' object has no attribute 'text'
我希望这是有道理的。我相信我所追求的是 DOM 解析方法,这很好,因为这些文档不是那么大。
我感谢任何正确方向的建议或指示。
您在上一行中将 tc
属性的值替换为 string
:
for tc in root.findall("./ndt/ndtran/tc"):
tft = tc.find('tft').text
tc = tc.find('tc').text
#^^ use different variable name here
esi = tc.find('esi').text
#^^ at this point, `tc` is no longer referencing the outer <tc> elements
有趣的巧合是 string
也有 find()
方法 return int
(-1
) 当找不到关键字时,因此 'int'对象没有属性'text'错误。
我的任务是将一些旧的 XML 解析代码重写为 Python,我偶然发现了 cElementTree
的乐趣,我喜欢它,因为我可以这样做这么多行。
我对 xpath
的经验水平不是那么广泛,这个问题更多的是关于进一步深入结构。
我在 test.xml
<?xml version="1.0"?>
<ownershipDocument>
<issue>
<ic>0000030305</ic>
<iname>DUCOMM</iname>
<its>DCP</its>
</issue>
<ndt>
<ndtran>
<tc>
<tft>4</tft>
<tc>P</tc>
<esi>0</esi>
</tc>
</ndtran>
<ndtran>
<tc>
<tft>4</tft>
<tc>P</tc>
<esi>0</esi>
</tc>
</ndtran>
</ndt>
</ownershipDocument>
我在 Python 中写了这个脚本:
import xml.etree.cElementTree as ET
tree = ET.parse('test.xml')
root = tree.getroot()
print root.tag
print root.attrib
for child in root:
print(child.tag, child.attrib)
for issue in root.findall('issue'):
ic = issue.find('ic').text
iname= issue.find('iname').text
print(ic,iname)
这给了我:
ownershipDocument
{}
('issue', {})
('ndt', {})
('0000030305', 'DUCOMM')
这成功地让我在 "issue" 中获得了我需要的信息。
问题是我需要访问多个 "ndtran" 节点(在 "ndt" 节点中)。在解析时,我可以提取 "tft"、"tc" 和 "esi" 值作为组,但我需要遍历每个 "tc" 节点,提取 "tft"、"tc","esi" 个值,将它们插入数据库,然后移动到下一个 "tc" 节点并再次执行。
我试图用来遍历每一个的是这样的:
for tc in root.findall("./ndt/ndtran/tc"):
tft = tc.find('tft').text
tc = tc.find('tc').text
esi = tc.find('esi').text
print(tft,tc,esi)
这几乎让我到达那里(我认为)但它确实给了我一个错误。
esi = tc.find('esi').text
AttributeError: 'int' object has no attribute 'text'
我希望这是有道理的。我相信我所追求的是 DOM 解析方法,这很好,因为这些文档不是那么大。
我感谢任何正确方向的建议或指示。
您在上一行中将 tc
属性的值替换为 string
:
for tc in root.findall("./ndt/ndtran/tc"):
tft = tc.find('tft').text
tc = tc.find('tc').text
#^^ use different variable name here
esi = tc.find('esi').text
#^^ at this point, `tc` is no longer referencing the outer <tc> elements
有趣的巧合是 string
也有 find()
方法 return int
(-1
) 当找不到关键字时,因此 'int'对象没有属性'text'错误。