2010-07-22 10 views
17

में व्हाइटस्पेस निकालें I 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 

मैं उपयोग नहीं कर सकते अजगर 2.7 जो method पैरामीटर प्रदान करेगा मैं निम्न पैकेज की कोशिश की।

minidom: सिर्फ एक ही:

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

यह lxml का उपयोग करके पाठ नोड http://stackoverflow.com से सभी रिक्त लाइनों और व्हाइट-स्पेस को दूर करने में मदद मिल सकती/ए/1 9 3 9 6130/9 736 99 – DevC

उत्तर

29

सबसे आसान समाधान शायद 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", जो मान्य होंगी उपयोग कर सकते हैं। एक और विकल्प एक डीटी का उपयोग करेगा और etree.XMLParser(load_dtd=True) का उपयोग करेगा, जहां पार्सर डीटी का उपयोग करेगा यह निर्धारित करने के लिए कि कौन सा व्हाइटस्पेस नोड महत्वपूर्ण हैं या नहीं।

उसके अलावा, आप सफेद स्थान को आप नहीं चाहते दूर करने के लिए अपने खुद के कोड लिखने के लिए होगा (वंश पुनरावृत्ति, और जहां उपयुक्त हो, सेट .text और .tail गुण है कि None या रिक्त स्ट्रिंग पर केवल रिक्त स्थान होते हैं)

+0

मैंने पाया है कि, जैसा कि @ स्टेवन द्वारा इंगित किया गया है, केवल कुछ सफेद तत्व वाले तत्व साफ़ नहीं किए गए हैं। मैंने 'etree.tostring' पर कॉल के बाद ऐसा करने के लिए एक रेगेक्स का उपयोग किया है:' re.sub (r '> \ s + <', '><', xml_str) ' – Rodrigue

+0

कृपया 'etree.XML (xml_str, parser = p)' पहले स्निपेट में 'etree.XML (xml_str, पार्सर = पार्सर)' के साथ। –

-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 होगा। हालांकि इसे किसी प्रकार के एक्सएमएल चेकर के साथ जांचना होगा। क्या आप वाकई एक्सएमएल चाहते हैं? क्या आपने लेख पढ़ा है: Python Is Not Java

+0

-1 आपका सुझाव कुछ भी मिटाएगा जैसे " \ t \ tfoo" " –

+0

मुझे जॉन से सहमत होना होगा। यह एक्सएमएल सिंटैक्स को बिल्कुल सुरक्षित नहीं करता है। – mattbasta

6

व्हाइटस्पेस एक XML दस्तावेज़ के भीतर महत्वपूर्ण है। इंडेंटेशन के लिए व्हाइटस्पेस का उपयोग एक्सएमएल का खराब उपयोग है, क्योंकि यह महत्वपूर्ण डेटा पेश करता है जहां वास्तव में कोई नहीं है - और दुख की बात है, यह आदर्श है। व्हाइटस्पेस को अलग करने के लिए आप जो भी प्रोग्रामेटिक दृष्टिकोण लेते हैं, सबसे अच्छा, अनुमान लगाया जाएगा - आपको डेटा के पैर के अंगों के कुछ हिस्सों पर कदम उठाए बिना, व्हाट्स स्पेस को ठीक से हटाने के लिए एक्सएमएल क्या संदेश दे रहा है, इसके बारे में बेहतर जानकारी चाहिए।

-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> 
-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) 

हालांकि, थानाटोस सही है। व्हाइटस्पेस एक्सएमएल में डेटा का प्रतिनिधित्व कर सकता है इसलिए सावधानी के साथ उपयोग करें।

17

यहाँ कुछ त्वरित मैं के साथ क्योंकि मैं 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 = ' ')) 

कौन सा मैं वास्तव में केवल-इंडेंट फिर से अन्यथा टूटी खरोज के साथ एक्सएमएल फ़ाइल की जरूरत है। यह preserve निर्देश का सम्मान नहीं करता है, लेकिन, ईमानदारी से, इसलिए एक्सएमएल से निपटने वाले कई अन्य सॉफ़्टवेयर करें, यह एक अजीब आवश्यकता है :) इसके अलावा, आप उपरोक्त कोड में आसानी से उस प्रकार की कार्यक्षमता को जोड़ सकेंगे (बस

+1

इसके लिए धन्यवाद - मैं अपनी परियोजना में lxml जोड़ना नहीं चाहता था और यह मेरी आवश्यकताओं के लिए पूरी तरह से काम किया। –

+2

बहुत बढ़िया। धन्यवाद दोस्त। –

0
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) 

this source

0

केवल एक चीज है कि मुझे xml.dom.minidom के toprettyxml (के बारे में परेशान से space विशेषता के लिए चेक करें, और recure नहीं है अपने मूल्य 'की रक्षा' है।)) कि है यह खाली रेखाएं जोड़ता है। मैं विभाजन के घटकों को नहीं है, तो मैं बस रिक्त लाइनों को हटाने के लिए एक सरल समारोह लिखा है:

#!/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 का उपयोग() अपने आप में, यानी प्रिंट (toprettyxml (x)), यह कहते हैं अनावश्यक रिक्त लाइनों:

<?xml version="1.0" ?> 
<monty> 


     <example>something</example> 


     <python>parrot</python> 


</monty> 
संबंधित मुद्दे