lxml.etree在python 3中不使用cdata

时间:2018-02-07 14:44:36

标签: python xml python-3.x lxml cdata

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

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

这是我做CDATA黑客的方式: https://blog.ionelmc.ro/2014/06/15/lxml-element-builder-and-cdata/

这是我更改文本值的方式(在" RESPONSE"标签中显示如下所示的XML): 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&#39;&#39;&#39;&#39;&#39;和&#39;&gt;&#39;标记为&lt;&gt;

1 个答案:

答案 0 :(得分:4)

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

你需要:

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