27

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パラメータを提供するPython2.7は使用できません。

ミニダム:まったく同じ:

xmlDocument = xml.dom.minidom.parseString(xmlStr)
xmlStr = xmlDocument.toprettyxml(indent='', newl='', encoding='UTF-8')
4

8 に答える 8

43

最も簡単な解決策は、おそらく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 と use を使用することetree.XMLParser(load_dtd=True)です。この場合、パーサーは dtd を使用して、どの空白ノードが重要かどうかを判断します。

それ以外では、不要な空白を削除する独自のコードを作成する必要があります (子孫を反復し、必要に応じて、空白または空の文字列のみを含むセット.text.tailプロパティを繰り返します)。None

于 2010-07-23T09:39:29.500 に答える
29

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、その値が「preserve」の場合は再修正しないでください。)

于 2013-06-04T13:23:31.947 に答える
7

空白はXMLドキュメント内で重要です。インデントに空白を使用することは、実際には存在しない重要なデータを導入するため、XMLの不適切な使用法です。悲しいことに、これは標準です。空白を取り除くためにあなたが取るプログラム的なアプローチは、せいぜい推測です-データの一部を踏まずに、空白を適切に取り除くために、XMLが何を伝えているかについてのより良い知識が必要です。

于 2010-07-22T22:44:29.093 に答える
1
xmlStr = xmlDocument.toprettyxml(indent='\t', newl='\n', encoding='UTF-8')
fix = re.compile(r'((?<=>)(\n[\t]*)(?=[^<\t]))|(?<=[^>\t])(\n[\t]*)(?=<)')
newXmlStr = re.sub(fix, '', xmlStr )

このソースから

于 2015-04-30T18:12:03.780 に答える
-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>
于 2012-11-09T20:54:40.653 に答える
-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)

しかし、タナトスは正しい。空白は XML のデータを表すことができるため、注意して使用してください。

于 2013-01-22T03:42:40.467 に答える
-3
xmlStr = ' '.join(xmlStr.split()))

これにより、すべてのテキストが 1 行にまとめられ、複数の空白が 1 つの空白に置き換えられます。

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

于 2010-07-22T15:45:06.457 に答える