python – 来自fromsting()和tostring()的lxml.etree没有返回相同的数据

我正在学习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>

转载注明原文:python – 来自fromsting()和tostring()的lxml.etree没有返回相同的数据 - 代码日志