我正在学习lxml(在使用ElementTree之后),我很困惑为什么.fromstring和.tostring似乎不可逆.这是我的例子:
import lxml.etree as ET
f = open('somefile.xml','r')
data = f.read()
tree_in = ET.fromstring(data)
tree_out = ET.tostring(tree_in)
f2 = open('samefile.xml','w')
f2.write(tree_out)
f2.close
‘somefile.xml’是132 KB.
‘samefile.xml’ – 输出 – 是113 KB,它在某个arbirtrary点缺少文件的结尾.整个树的结束标记和最终元素的一些部分刚刚消失.
我的代码有问题,或者原始XML文件中的嵌套是否有问题?如果是这样,我是否*再次使用ElementTree的BeautifulSoup(没有xpath)?
一个注意事项:许多元素中的文本都有一堆被转换为文本的废话,但这是导致这个问题的原因吗?
例:
<QuestionIndex Id="Perm"><Answer><![CDATA[confirm]]></Answer><Answer><![CDATA[NotConfirm]]></Answer></QuestionIndex>
<QuestionIndex Id="Actor"><Answer><![CDATA[GirlLt16]]></Answer><Answer><![CDATA[Fem17to25]]></Answer><Answer><![CDATA[BoyLt16]]></Answer><Answer><![CDATA[Mal17to25]]></Answer><Answer><![CDATA[Moth]]></Answer><Answer><![CDATA[Fath]]></Answer><Answer><![CDATA[Elder]]></Answer><Answer><![CDATA[RelLead]]></Answer><Answer><![CDATA[Auth]]></Answer><Answer><![CDATA[Teach]]></Answer><Answer><![CDATA[Oth]]></Answer></QuestionIndex>
解决方法:
没有一个完整的可重复的例子,很难解释“在一些arbirtrary点缺少文件的结尾”的问题.
但我怀疑你所谓的“一堆垃圾”是CDATA sections.你的例子中有几个(这不是一个格式良好的XML文档,顺便说一下).
通常,XML解析器没有义务保持CDATA部分的完整性.标记如
<Answer><![CDATA[confirm]]></Answer>
相当于
<Answer>confirm</Answer>
但是,lxml.etree.XMLParser
类采用strip_cdata参数,可用于保留CDATA节.可以将解析器的实例传递给etree.fromstring().这是一个例子:
from lxml import etree
XML = '<QuestionIndex Id="Perm"><Answer><![CDATA[confirm]]></Answer></QuestionIndex>'
print "Original size:", len(XML)
tree1 = etree.fromstring(XML)
out = etree.tostring(tree1)
print "With CDATA stripped:", len(out)
print out
parser = etree.XMLParser(strip_cdata=False)
tree2 = etree.fromstring(XML, parser)
out = etree.tostring(tree2)
print "With CDATA kept:", len(out)
print out
=>
Original size: 77
With CDATA stripped: 65
<QuestionIndex Id="Perm"><Answer>confirm</Answer></QuestionIndex>
With CDATA kept: 77
<QuestionIndex Id="Perm"><Answer><![CDATA[confirm]]></Answer></QuestionIndex>