lxml.etree 在 python 3 中不使用 cdata

lxml.etree not working with cdata in python 3

我想用 LXML 将 XML 文件中的值更改为 CDATA。

当我简单地更改文本时它完美地工作,但是当使用 CDATA 时,元素的内容没有被替换。

这就是我进行 CDATA 破解的方式: https://blog.ionelmc.ro/2014/06/15/lxml-element-builder-and-cdata/

这是我更改文本值的方式(在 XML 中的 "RESPONSE" 标记之间,如下所示): Change text value with lxml

问题:如何将 RESPONSE 标签的内容文本更改为 CDATA?

from lxml import etree
from lxml.builder import ElementMaker
from lxml.etree import CDATA


def add_cdata(element, cdata):
    assert not element.text, "Can't add a CDATA section. Element already has some text: %r" % element.text
    element.text = cdata

E = ElementMaker(typemap={
    CDATA: add_cdata
})

print("\nThe CDATA is working here perfectly: ")
print(etree.tostring(E.RESPONSE(CDATA('Some stuff that needs to be in a CDATA section'))))

tree = etree.fromstring('''<REQRES_MAPPING>
    <REQUEST>aaa</REQUEST>
    <RESPONSE>bbb</RESPONSE>
</REQRES_MAPPING>''')

print("\nThe data I need to change: ")
print(etree.tostring(tree))


response = tree.xpath("//RESPONSE")
if response:
    response[0].text = 'xxx'                   # this is working, but I need CDATA

print("\nThe text has changed between the RESPONSE tags: ")
print(etree.tostring(tree))


if response:
    response[0] = E.RESPONSE(CDATA('xxx'))     # this is not working

print("\nThis is not working here: ")
print(etree.tostring(tree))

我想得到的:

<REQRES_MAPPING>
    <REQUEST>aaa</REQUEST>
    <RESPONSE><![CDATA[yyy]]</RESPONSE>
</REQRES_MAPPING>

显然用CDATA修饰符插入yyy不是一个好方法,因为最后LMXL会将CDATA的'<'和'>'标签改为&lt;&gt;

通过执行 response[0] = ...,您只是在修改名为 [=12th=] 的列表,您实际上根本没有触及 tree

你需要:

tree.xpath("//RESPONSE")[0].text = CDATA('xxx')