使用 ElementTree 访问 xml 文件中的元素和标记时获取空列表
Getting empty list when accessing element and tag in xml file using ElementTree
想法是为以下 xml
:
获取标签 endTime
的值
<epochs xmlns="http://www.egi.com/epochs_mff" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<epoch>
<beginTime>0</beginTime>
<endTime>3586221000</endTime>
<firstBlock>1</firstBlock>
<lastBlock>897</lastBlock>
</epoch>
<epoch>
<beginTime>3750143000</beginTime>
<endTime>5549485000</endTime>
<firstBlock>898</firstBlock>
<lastBlock>1347</lastBlock>
</epoch>
</epochs>
但是,直接访问标签 return 一个空列表:
import xml.etree.ElementTree as ET
tree = ET.parse(r'epochs.xml')
epoch_list=tree.findall("epoch")
但是,遍历 tree
会 return endTime
值。
import xml.etree.ElementTree as ET
tree = ET.parse(r'epochs.xml')
for elem in tree:
for subelem in elem:
print(subelem.text)
请问如何直接获取值为300937000的endTime
?
您的代码失败的原因是您的 XML 使用了默认命名空间
(xmlns="http://...").
但是你对 findall 的调用包含 epoch 而没有 任何命名空间,所以它不是
可能会找到任何东西。
要处理 namespaced XML,您必须:
- 创建已用命名空间的字典({前缀:命名空间}),
- 在 XPath 表达式中包含相关命名空间的前缀,
- 将上述字典作为findall的第二个参数传递。
类似于:
ns = {'ep': 'http://www.egi.com/epochs_mff'}
epoch_list = tree.findall('ep:epoch', ns)
则结果为:
[<Element '{http://www.egi.com/epochs_mff}epoch' at 0x...>]
并获取 endTime 元素的内容,如果您不关心
XML 树中的任何中间元素,运行:
tree.findtext('.//ep:endTime', namespaces=ns)
其他选择是通过完整的XML路径,从内容开始
根元素,但请记住每一步的命名空间前缀:
tree.findtext('ep:epoch/ep:endTime', namespaces=ns)
如果您有 多个 endTime 个元素,可能的解决方案之一
就是循环处理。
这次 findtext 没有用,因为它只找到第一个匹配的元素。
您应该使用基于 findall 的循环,然后(在循环内)
检索当前元素的文本并按预期使用它,
例如:
for it in tree.findall('ep:epoch/ep:endTime', namespaces=ns):
print(it.text)
当然,把print替换成任何你需要消耗的
找到文本。
想法是为以下 xml
:
endTime
的值
<epochs xmlns="http://www.egi.com/epochs_mff" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<epoch>
<beginTime>0</beginTime>
<endTime>3586221000</endTime>
<firstBlock>1</firstBlock>
<lastBlock>897</lastBlock>
</epoch>
<epoch>
<beginTime>3750143000</beginTime>
<endTime>5549485000</endTime>
<firstBlock>898</firstBlock>
<lastBlock>1347</lastBlock>
</epoch>
</epochs>
但是,直接访问标签 return 一个空列表:
import xml.etree.ElementTree as ET
tree = ET.parse(r'epochs.xml')
epoch_list=tree.findall("epoch")
但是,遍历 tree
会 return endTime
值。
import xml.etree.ElementTree as ET
tree = ET.parse(r'epochs.xml')
for elem in tree:
for subelem in elem:
print(subelem.text)
请问如何直接获取值为300937000的endTime
?
您的代码失败的原因是您的 XML 使用了默认命名空间 (xmlns="http://...").
但是你对 findall 的调用包含 epoch 而没有 任何命名空间,所以它不是 可能会找到任何东西。
要处理 namespaced XML,您必须:
- 创建已用命名空间的字典({前缀:命名空间}),
- 在 XPath 表达式中包含相关命名空间的前缀,
- 将上述字典作为findall的第二个参数传递。
类似于:
ns = {'ep': 'http://www.egi.com/epochs_mff'}
epoch_list = tree.findall('ep:epoch', ns)
则结果为:
[<Element '{http://www.egi.com/epochs_mff}epoch' at 0x...>]
并获取 endTime 元素的内容,如果您不关心 XML 树中的任何中间元素,运行:
tree.findtext('.//ep:endTime', namespaces=ns)
其他选择是通过完整的XML路径,从内容开始 根元素,但请记住每一步的命名空间前缀:
tree.findtext('ep:epoch/ep:endTime', namespaces=ns)
如果您有 多个 endTime 个元素,可能的解决方案之一 就是循环处理。
这次 findtext 没有用,因为它只找到第一个匹配的元素。 您应该使用基于 findall 的循环,然后(在循环内) 检索当前元素的文本并按预期使用它, 例如:
for it in tree.findall('ep:epoch/ep:endTime', namespaces=ns):
print(it.text)
当然,把print替换成任何你需要消耗的 找到文本。