如何在Python 2.6中删除XML字符串中的空格和换行符?我尝试了以下软件包:
etree:此代码段保留原始空格:
xmlStr = '''<root>
<head></head>
<content></content>
</root>'''
xmlElement = xml.etree.ElementTree.XML(xmlStr)
xmlStr = xml.etree.ElementTree.tostring(xmlElement, 'UTF-8')
print xmlStr
我不能使用提供method
参数的Python 2.7。
minidom:就是一样:
xmlDocument = xml.dom.minidom.parseString(xmlStr)
xmlStr = xmlDocument.toprettyxml(indent='', newl='', encoding='UTF-8')
答案 0 :(得分:34)
最简单的解决方案可能是使用lxml,您可以在其中设置解析器选项以忽略元素之间的空白区域:
>>> from lxml import etree
>>> parser = etree.XMLParser(remove_blank_text=True)
>>> xml_str = '''<root>
>>> <head></head>
>>> <content></content>
>>> </root>'''
>>> elem = etree.XML(xml_str, parser=parser)
>>> print etree.tostring(elem)
<root><head/><content/></root>
这可能足以满足您的需求,但有些警告是安全的:
这将删除元素之间的空白节点,并尝试不删除具有混合内容的元素内的空白节点:
>>> elem = etree.XML('<p> spam <a>ham</a> <a>eggs</a></p>', parser=parser)
>>> print etree.tostring(elem)
<p> spam <a>ham</a> <a>eggs</a></p>
不会删除文本节点中的前导或尾随空格。但是,在某些情况下,它仍将从混合内容中删除空白节点:如果解析器尚未在该级别遇到非空白节点。
>>> elem = etree.XML('<p><a> ham</a> <a>eggs</a></p>', parser=parser)
>>> print etree.tostring(elem)
<p><a> ham</a><a>eggs</a></p>
如果您不想这样,可以使用xml:space="preserve"
,这将得到尊重。另一种选择是使用dtd并使用etree.XMLParser(load_dtd=True)
,其中解析器将使用dtd来确定哪些空白节点是重要的。
除此之外,您必须编写自己的代码来删除不需要的空格(迭代后代,并在适当的情况下,设置仅包含空格的.text
和.tail
属性None
或空字符串)
答案 1 :(得分:19)
我想出了一些快速的东西,因为我不想使用lxml:
from xml.dom import minidom
from xml.dom.minidom import Node
def remove_blanks(node):
for x in node.childNodes:
if x.nodeType == Node.TEXT_NODE:
if x.nodeValue:
x.nodeValue = x.nodeValue.strip()
elif x.nodeType == Node.ELEMENT_NODE:
remove_blanks(x)
xml = minidom.parse('file.xml')
remove_blanks(xml)
xml.normalize()
with file('file.xml', 'w') as result:
result.write(xml.toprettyxml(indent = ' '))
我真的只需要用缩小的缩进来重新缩进XML文件。它不尊重preserve
指令,但老实说,许多其他处理XML的软件也是如此,这是一个有趣的要求:)此外,你可以轻松地添加这种功能上面的代码(仅检查space
属性,如果其值为“保留”,则不会恢复。)
答案 2 :(得分:7)
空格在XML文档中很重要。使用空格进行缩进是对XML的一种不良使用,因为它引入了重要的数据,而实际上并没有 - 而且遗憾的是,这是常态。你用来剥离空白的任何程序化方法都充其量只是猜测 - 你需要更好地了解XML正在传达什么来正确删除空格,而不是踩到一些数据的脚趾。
答案 3 :(得分:0)
唯一让我困扰xml.dom.minidom的toprettyxml()的是它添加空行。我似乎没有得到拆分组件,所以我只写了一个简单的函数来删除空行:
#!/usr/bin/env python
import xml.dom.minidom
# toprettyxml() without the blank lines
def prettyPrint(x):
for line in x.toprettyxml().split('\n'):
if not line.strip() == '':
print line
xml_string = "<monty>\n<example>something</example>\n<python>parrot</python>\n</monty>"
# parse XML
x = xml.dom.minidom.parseString(xml_string)
# clean
prettyPrint(x)
这就是代码输出的内容:
<?xml version="1.0" ?>
<monty>
<example>something</example>
<python>parrot</python>
</monty>
如果我单独使用toprettyxml(),即print(toprettyxml(x)),则会添加不必要的空行:
<?xml version="1.0" ?>
<monty>
<example>something</example>
<python>parrot</python>
</monty>
答案 4 :(得分:-1)
有点笨拙的解决方案没有lxml : - )
data = """<root>
<head></head> <content></content>
</root>"""
data3 = []
data2 = data.split('\n')
for x in data2:
y = x.strip()
if y: data3.append(y)
data4 = ''.join(data3)
data5 = data4.replace(" ","").replace("> <","><")
print data5
Output: <root><head></head><content></content></root>
答案 5 :(得分:-1)
如果“非叶子”节点中的空格是我们要删除的内容,则以下函数将执行此操作(如果指定则递归):
from xml.dom import Node
def stripNode(node, recurse=False):
nodesToRemove = []
nodeToBeStripped = False
for childNode in node.childNodes:
# list empty text nodes (to remove if any should be)
if (childNode.nodeType == Node.TEXT_NODE and childNode.nodeValue.strip() == ""):
nodesToRemove.append(childNode)
# only remove empty text nodes if not a leaf node (i.e. a child element exists)
if childNode.nodeType == Node.ELEMENT_NODE:
nodeToBeStripped = True
# remove flagged text nodes
if nodeToBeStripped:
for childNode in nodesToRemove:
node.removeChild(childNode)
# recurse if specified
if recurse:
for childNode in node.childNodes:
stripNode(childNode, True)
然而,Thanatos是正确的。空格可以用XML表示数据,因此请谨慎使用。
答案 6 :(得分:-3)
xmlStr = ' '.join(xmlStr.split()))
这会将所有文本放在一行中,用一个空格替换多个空格。
xmlStr = ''.join(xmlStr.split()))
这将删除包含文本内部空格的完整空间,并且无法使用。
对于您提供的输入,第一个表格可以与风险(但您要求)一起使用:
xmlStr = '''<root>
<head></head>
<content></content>
</root>'''
xmlStr = ' '.join(xmlStr.split())
print xmlStr
""" Output:
<root> <head></head> <content></content> </root>
"""
这将是有效的xml。它可能需要使用某种xml检查器进行检查。您是否确定要使用XML?你读过这篇文章了吗: Python Is Not Java