我需要删除xml标记之间的空格,例如,如果原始xml看起来像:
<node1>
<node2>
<node3>foo</node3>
</node2>
</node1>
Run Code Online (Sandbox Code Playgroud)
我希望将最终结果压缩成单行:
<node1><node2><node3>foo</node3></node2></node1>
Run Code Online (Sandbox Code Playgroud)
请注意,我无法控制xml结构,因此解决方案应该足够通用,以便能够处理任何有效的xml.此外,xml可能包含CDATA块,我需要将其从此运算中排除并保持原样.
到目前为止,我有几个想法:(1)将xml解析为文本并查找标记的开始和结束<和>(2)另一种方法是加载xml文档并逐个节点地打印出一个新的通过连接标签来记录文档.
我认为任何一种方法都可行,但我宁愿不在这里重新发明轮子,所以可能有一个python库已经做了这样的事情?如果没有,那么在推出我自己的计算器时需要注意的任何问题/陷阱?有什么建议?
编辑 谢谢大家的回答/建议,Triptych和Van Gale的解决方案都适合我,并且完全符合我的要求.希望我能接受这两个答案.
这很容易用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)
Run Code Online (Sandbox Code Playgroud)
结果是:
<node1><node2><node3>foo </node3></node2></node1>
Run Code Online (Sandbox Code Playgroud)
编辑: Triptych的回答提醒我有关CDATA的要求,因此创建解析器对象的行应该看起来像这样:
parser = etree.XMLParser(remove_blank_text=True, strip_cdata=False)
Run Code Online (Sandbox Code Playgroud)
我使用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>
Run Code Online (Sandbox Code Playgroud)
这应该够了吧.
在python中你可以使用lxml(直接链接到主页上的示例)来转换它.
对于某些测试,请使用xsltproc,示例:
xsltproc test.xsl test.xml
Run Code Online (Sandbox Code Playgroud)
test.xsl上面的文件和test.xmlXML文件在哪里.
使用 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
Run Code Online (Sandbox Code Playgroud)