lxml处理CDATA的备忘

lxml是python的库,可用于解析、处理xml文件及HTML文件。

在工作中,遇到需要对原有的xml文件进行改写,根据需要增加、删除或改写一些元素。具体的做法是先用lxml将文件解析为内存里的dom树结构,再通过lxml提供的方法对元素进行增、删、改、查等操作,最后再将内存里的dom树落回文件。

示例代码如下:

1 from lxml import etree
2 root = etree.fromstring(str_xml)  # here parse dom tree from a xml string.
3 
4 # here do some update on root.
5 # ........
6 # update finish.
7 
8 str_final_xml = etree.tostring(self.root, encoding='utf-8', xml_declaration=True)  # here serialize dom tree to a string. 

先解析,然后通过一系列查找,修改,增加,删除等操作,root对应的dom树变为我们想要的结果,再将结果dom树序列化为字符串。

这里遇到了一个问题。

原来的CDATA标签在重新写入后都不见了。在网上找了一些讨论,才知道原来CDATA在XML中不是必须的,所以默认去掉了。

如果想保留原来的CDATA,需要在解析xml时自己定义一个解析器。

代码如下所示:

 1 from lxml import etree
 2 
 3 parser = etree.XMLParser(strip_cdata=False)
 4 root = etree.fromstring(str_xml, parser)  # here parse dom tree from a xml string.
 5 
 6 # here do some update on root.
 7 # ........
 8 # update finish.
 9 
10 str_final_xml = etree.tostring(self.root, encoding='utf-8', xml_declaration=True)  # here serialize dom tree to a string. 

第3行自己定义了一个解析器,参数strip_cdata置为False,这个参数默认是开启的。在调用fromstring时带上这个解析器。这样将dom树再序列化后原始的CDATA就可以保留下来。

如果需要写入一个CDATA元素,lxml也能很高支持。

>>>elem = etree.Element('root')
>>>elem.text = etree.CDATA('this is root.')
>>>
>>>print etree.tostring(elem)

<root><![CDATA[this is root.]]></root>

只需要将待写入的字符用etree.CDATA封装即可。

原文地址:https://www.cnblogs.com/terencezhou/p/2683371.html