我需要删除xml标记之间的空格,例如如果原始的xml看起来像:
<node1>
<node2>
<node3>foo</node3>
</node2>
</node1>
我希望最终结果是 crunched 到单行:
<node1><node2><node3>foo</node3></node2></node1>
请注意,我无法控制xml结构,因此解决方案应该足够通用,以便能够处理任何有效的xml。此外,xml可能包含CDATA块,我需要从 crunching 中排除这些块并保持原样。
到目前为止,我有几个想法:(1)将xml解析为文本并查找标记的开头和结尾&lt;和&gt; (2)另一种方法是加载xml文档并逐个节点地输出并通过连接标记打印出 new 文档。
我认为任何一种方法都可行,但我宁愿不在这里重新发明轮子,所以可能有一个python库已经做了这样的事情?如果没有,那么在推出我自己的 cruncher 时需要注意的任何问题/陷阱?有什么建议吗?
修改的 谢谢大家的回答/建议,Triptych和Van Gale的解决方案都适合我,并且完全符合我的要求。希望我能接受这两个答案。
答案 0 :(得分:8)
使用lxml很容易处理(注意:这个特殊功能不在ElementTree中):
from lxml import etree
parser = etree.XMLParser(remove_blank_text=True)
foo = """<node1>
<node2>
<node3>foo </node3>
</node2>
</node1>"""
bar = etree.XML(foo, parser)
print etree.tostring(bar,pretty_print=False,with_tail=True)
结果:
<node1><node2><node3>foo </node3></node2></node1>
编辑: Triptych的回答提醒我有关CDATA的要求,因此创建解析器对象的行实际上应如下所示:
parser = etree.XMLParser(remove_blank_text=True, strip_cdata=False)
答案 1 :(得分:5)
我使用XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这应该可以解决问题。
在python中,您可以使用lxml (direct link to sample on homepage)对其进行转换。
对于某些测试,请使用xsltproc
,示例:
xsltproc test.xsl test.xml
其中test.xsl
是上面的文件,test.xml
是您的XML文件。
答案 2 :(得分:4)
使用BeautifulSoup非常简单。
此解决方案假设可以从字符数据的尾端删除空格
示例:<foo> bar </foo>
变为<foo>bar</foo>
它会正确地忽略评论和CDATA。
import BeautifulSoup
s = """
<node1>
<node2>
<node3>foo</node3>
</node2>
<node3>
<!-- I'm a comment! Leave me be! -->
</node3>
<node4>
<![CDATA[
I'm CDATA! Changing me would be bad!
]]>
</node4>
</node1>
"""
soup = BeautifulSoup.BeautifulStoneSoup(s)
for t in soup.findAll(text=True):
if type(t) is BeautifulSoup.NavigableString: # Ignores comments and CDATA
t.replaceWith(t.strip())
print soup
答案 3 :(得分:2)
不是解决方案,但是因为你提出了建议:我建议你不要自己解析(除非你想学习如何编写一个复杂的解析器)因为,正如你所说,并不是所有空格都应该删除。不仅有CDATA块,还有带有“xml:space = preserve”属性的元素,它们对应于XHTML中的<pre>
(封闭的空格实际上有意义),并编写了一个能够解析的解析器认识到这些元素,只留下白色空间是可能的,但却是令人不快的。
我会使用解析方法,即加载文档并逐个节点地打印出来。这样,您可以轻松识别哪些节点可以剥离空间,哪些节点不可以。 Python标准库中有一些模块,我从未使用过这些模块;-)对您有用...尝试xml.dom
,或者我不确定您是否可以使用{{xml.parsers.expat
执行此操作1}}。