【问题标题】:Prepend or append PI before / after the root element with lxml使用 lxml 在根元素之前/之后添加或添加 PI
【发布时间】:2020-05-29 17:24:36
【问题描述】:

使用 lxml,我如何在根元素之前添加处理指令,或者在使用 lxml 的根元素之后添加 PI。

目前,以下示例不起作用:

from lxml import etree

root = etree.XML("<ROOT/>")
root.addprevious(etree.ProcessingInstruction("foo"))
print(etree.tounicode(root))

我明白了:

<ROOT/>

代替:

<?foo?><ROOT/>

【问题讨论】:

    标签: python lxml processing-instruction


    【解决方案1】:

    你需要在tounicode()中使用ElementTree,而不仅仅是Element

    from lxml import etree
    
    root = etree.XML("<ROOT/>")
    root.addprevious(etree.ProcessingInstruction("foo"))
    print(etree.tounicode(root.getroottree()))
    

    输出几乎就是你想要的:

    <?foo ?><ROOT/>
    

    foo 之后出现额外的空格字符,因为 lxmlPI 呈现为 pi.target + " " + pi.text

    【讨论】:

    • 我看到有人支持这个答案,但正确的答案是使用etree.tounicode(root.getroottree()):无需创建新的ElementTree。您可以编辑您的答案,以便我接受。
    【解决方案2】:

    实际上,Element 始终附加到 ElementTree,即使它看起来“分离”:

    root = etree.XML("<ROOT/>")
    assert root.getroottree() is not None
    

    当我们使用addprevious/addnext 在根元素之前/之后插入处理指令时,PI 不会附加到父元素(没有任何父元素),而是附加到根树.

    所以,问题在于tounicode(或tostring)的使用。最佳做法是打印根树的 XML,而不是根元素。

    from lxml import etree
    
    root = etree.XML("<ROOT/>")
    root.addprevious(etree.ProcessingInstruction("foo"))
    root.addnext(etree.ProcessingInstruction("bar"))
    
    print(etree.tounicode(root))
    # => "<ROOT/>"
    
    print(etree.tounicode(root.getroottree()))
    # => "<?foo ?><ROOT/><?bar ?>"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-22
      • 1970-01-01
      • 2012-08-26
      • 1970-01-01
      • 1970-01-01
      • 2012-01-07
      • 1970-01-01
      • 2019-11-26
      相关资源
      最近更新 更多