Python中用lxml获取XML指定元素文本报错的解决方法
解决Python中lxml查找XML指定元素文本的问题
问题场景
给定以下XML片段:
<root> <doc> <field name="id">metadata_9606_SAMN03465421</field> <field name="is_metadata">true</field> <field name="is_sample">true</field> <field name="project_desc">PRJNA280600</field> <field name="taxid">9606</field> <field name="source_name">uterus</field> <field name="sample_id">SAMN03465421</field> <field name="exp_Mcount">13341.1</field> </doc> <doc> <field name="id">1_SAMN03465421</field> <field name="gene">1</field> <field name="sample_id">SAMN03465421</field> <field name="source_name">uterus</field><field name="var">0</field> <field name="full_rpkm">0.133911</field> <field name="exp_rpkm">0.134</field> <field name="exp_total">3155</field> <field name="project_desc">PRJNA280600</field> </doc> <doc> <field name="id">1_SAMN03465420</field> <field name="gene">1</field> <field name="sample_id">SAMN03465420</field> <field name="source_name">trachea</field><field name="var">0</field> <field name="full_rpkm">0.0232912</field> <field name="exp_rpkm">0.0233</field> <field name="exp_total">604</field> <field name="project_desc">PRJNA280600</field> </doc> </root>
用户尝试用以下代码查找每个<doc>下name属性为source_name的<field>元素文本:
import lxml.etree tree = lxml.etree.parse(<PATH TO DOCUMENT>) root = tree.getroot() print(root.findall('/doc/field name[4]'))
运行后出现错误:
Traceback (most recent call last): File "/home/alex/PycharmProjects/gene_expression_ftp/main.py", line 4, in <module> print(root.findall('/doc/field name[4]')) File "src/lxml/etree.pyx", line 1575, in lxml.etree._Element.findall File "src/lxml/_elementpath.py", line 334, in lxml._elementpath.findall File "src/lxml/_elementpath.py", line 312, in lxml._elementpath.iterfind File "src/lxml/_elementpath.py", line 281, in lxml._elementpath._build_path_iterator SyntaxError: cannot use absolute path on element
错误原因
- 绝对路径使用错误:
root已经是<root>元素,使用/doc会被当作绝对路径(从文档根开始),而非相对于root的路径,触发语法错误。 - XPath属性筛选语法错误:筛选
name属性为source_name的元素,正确语法是field[@name='source_name'],而非field name[4]。
正确实现方式
方式一:使用正确的相对XPath
import lxml.etree tree = lxml.etree.parse("<PATH TO DOCUMENT>") root = tree.getroot() # 查找所有doc下name为source_name的field元素 source_fields = root.findall("./doc/field[@name='source_name']") # 遍历并打印每个元素的文本 for field in source_fields: print(field.text)
方式二:遍历每个doc元素再查找目标field
如果需要同时获取doc下其他关联信息,这种方式更灵活:
import lxml.etree tree = lxml.etree.parse("<PATH TO DOCUMENT>") root = tree.getroot() for doc in root.findall("./doc"): # 在当前doc下查找目标field source_field = doc.find("./field[@name='source_name']") if source_field is not None: print(source_field.text)
运行以上代码会输出:
uterus uterus trachea
内容的提问来源于stack exchange,提问作者user18544188
相关产品推荐
相关产品推荐

