使用lxml的etree.iter获取单个子节点时返回多余兄弟节点如何解决
问题原因
你遇到的序列化异常是旧版lxml的已知bug:2.x及更早版本的etree.tostring()方法处理非根节点时,会错误将当前节点之后的所有同级节点、父节点闭合标签一同输出,和iter()遍历逻辑无关。你后续定位到的版本问题是完全正确的。
解决方案
方案1(推荐)
升级lxml到3.0及以上稳定版本,你的原有代码无需任何修改,即可得到预期的单个user节点输出。新版本已修复该序列化bug,root.iter("user")会正确遍历所有独立的user节点,etree.tostring()仅会序列化当前节点及其子节点。
方案2(兼容旧版本,无需升级)
如果受环境限制无法升级lxml,可在etree.tostring()中添加with_tail=False参数,强制不输出当前节点的尾内容,也可以改用findall()方法匹配子节点,示例代码如下:
from lxml import etree root = etree.XML("<users><user><name>Test</name><id>01</id></user> \ <user><name>Test</name><id>02</id></user> \ <user><name>Test</name><id>03</id></user></users>") for record in root.findall("user"): # with_tail=False 禁止输出当前节点结束标签后的额外内容 print(etree.tostring(record, with_tail=False))
运行上述代码即可得到你期望的输出:
b'<user><name>Test</name><id>01</id></user>' b'<user><name>Test</name><id>02</id></user>' b'<user><name>Test</name><id>03</id></user>'
内容的提问来源于stack exchange,提问作者timtom
相关产品推荐
相关产品推荐

