2015-11-06 13 views
8

में दृढ़ता से टिप्पणियां संरक्षित करें मैं एक्सएमएल में हेरफेर करते समय टिप्पणियों को यथासंभव विश्वसनीय रूप से संरक्षित करना चाहता हूं।पार्स किए गए एक्सएमएल (पायथन 2.7)

मैं टिप्पणियों को संरक्षित रखने में कामयाब रहा, लेकिन सामग्री एक्सएमएल से बच रही है।

#!/usr/bin/env python 
# add_host_to_tomcat.py 

import xml.etree.ElementTree as ET 
from CommentedTreeBuilder import CommentedTreeBuilder 
parser = CommentedTreeBuilder() 

if __name__ == '__main__': 
    filename = "/opt/lucee/tomcat/conf/server.xml" 

    # this is the important part: use the comment-preserving parser 
    tree = ET.parse(filename, parser) 

    # get the node to add a child to 
    engine_node = tree.find("./Service/Engine") 

    # add a node: Engine.Host 
    host_node = ET.SubElement(
     engine_node, 
     "Host", 
     name="local.mysite.com", 
     appBase="webapps" 
    ) 
    # add a child to new node: Engine.Host.Context 
    ET.SubElement(
     host_node, 
     'Context', 
     path="", 
     docBase="/path/to/doc/base" 
    ) 

    tree.write('out.xml') 
#!/usr/bin/env python 
# CommentedTreeBuilder.py 

from xml.etree import ElementTree 

class CommentedTreeBuilder (ElementTree.XMLTreeBuilder): 
    def __init__ (self, html = 0, target = None): 
     ElementTree.XMLTreeBuilder.__init__(self, html, target) 
     self._parser.CommentHandler = self.handle_comment 

    def handle_comment (self, data): 
     self._target.start(ElementTree.Comment, {}) 
     self._target.data(data) 
     self._target.end(ElementTree.Comment) 

हालांकि, की तरह की तरह की टिप्पणियां:

<!-- 
EXAMPLE HOST ENTRY: 
    <Host name="lucee.org" appBase="webapps"> 
     <Context path="" docBase="/var/sites/getrailo.org" /> 
    <Alias>www.lucee.org</Alias> 
    <Alias>my.lucee.org</Alias> 
    </Host> 

HOST ENTRY TEMPLATE: 
    <Host name="[ENTER DOMAIN NAME]" appBase="webapps"> 
     <Context path="" docBase="[ENTER SYSTEM PATH]" /> 
    <Alias>[ENTER DOMAIN ALIAS]</Alias> 
    </Host> 
    --> 

अंत के रूप में:

<!-- 
      EXAMPLE HOST ENTRY: 
    &lt;Host name="lucee.org" appBase="webapps"&gt; 
     &lt;Context path="" docBase="/var/sites/getrailo.org" /&gt; 
     &lt;Alias&gt;www.lucee.org&lt;/Alias&gt; 
     &lt;Alias&gt;my.lucee.org&lt;/Alias&gt; 
    &lt;/Host&gt; 

    HOST ENTRY TEMPLATE: 
    &lt;Host name="[ENTER DOMAIN NAME]" appBase="webapps"&gt; 
     &lt;Context path="" docBase="[ENTER SYSTEM PATH]" /&gt; 
     &lt;Alias&gt;[ENTER DOMAIN ALIAS]&lt;/Alias&gt; 
    &lt;/Host&gt; 
    --> 

मैं भी self._target.data(saxutils.unescape(data))CommentedTreeBuilder.py में करने की कोशिश की है, लेकिन यह कुछ भी करने को नहीं मालूम था । वास्तव में, मुझे लगता है कि समस्या handle_commment() चरण के बाद कहीं भी होती है।

वैसे, यह प्रश्न this जैसा है।

उत्तर

8

पायथन 2.7 और 3.5 के साथ परीक्षण किया गया, निम्न कोड को इरादे के अनुसार काम करना चाहिए।

#!/usr/bin/env python 
# CommentedTreeBuilder.py 
from xml.etree import ElementTree 

class CommentedTreeBuilder(ElementTree.TreeBuilder): 
    def __init__(self, *args, **kwargs): 
     super(CommentedTreeBuilder, self).__init__(*args, **kwargs) 

    def comment(self, data): 
     self.start(ElementTree.Comment, {}) 
     self.data(data) 
     self.end(ElementTree.Comment) 

फिर, मुख्य कोड उपयोग

parser = ET.XMLParser(target=CommentedTreeBuilder()) 

पार्सर के बजाय मौजूदा एक के रूप में में।

वैसे, टिप्पणियां lxml के साथ बॉक्स से ठीक से काम करती हैं। यही है, आप बस

import lxml.etree as ET 
tree = ET.parse(filename) 

उपरोक्त में से किसी एक की आवश्यकता के बिना कर सकते हैं।

+0

दोनों समाधान टिप्पणियों को संरक्षित करते हैं, धन्यवाद! लेकिन अन्य तत्व पुनः स्वरूपित होते हैं (और गुणों को पुन: व्यवस्थित, संभावित रूप से)। मुझे पता है कि यह मशीन-पठनीयता के लिए कोई फर्क नहीं पड़ता, लेकिन मेरे उद्देश्यों के लिए (मानव पठनीयता, संस्करण नियंत्रण, और केवल स्पष्ट रूप से छूने वाले तत्वों को छूना), यह महत्वपूर्ण है। एफडब्ल्यूआईडब्ल्यू, मेरा मूल संस्करण अन्य तत्वों को बरकरार रखने के लिए होता है (यानी मूल रूप से प्रारूपित किया गया था)। यह उत्तर मेरे स्पष्ट प्रश्न को संबोधित करता है, इसलिए इसे उत्तर पुरस्कार मिलेगा, लेकिन मैं जानना चाहता हूं कि गैर-टिप्पणी-तत्व प्रारूपण संरक्षण भी संभव है या नहीं। –

+0

जहां तक ​​मैं देख सकता हूं, संशोधित होने वाली एकमात्र चीजें गुणों का क्रम और टैग के अंदर सफेद जगह का क्रम है (अगर मुझे कुछ याद आ रहा है तो मुझे सही करें)। आप आमतौर पर बाद के बारे में नहीं होना चाहिए या देखभाल नहीं करनी चाहिए। चूंकि गुण 'xml' में किसी शब्दकोश में संग्रहीत होते हैं, इसलिए उनका ऑर्डर आउटपुट में यादृच्छिक होता है। इसे ठीक करने के लिए, आप टिप्पणियों के समान वर्कअराउंड का उपयोग कर सकते हैं, http://stackoverflow.com/q/2741480/2997179 देखें। या 'lxml' के साथ त्वरित परीक्षण के रूप में दिखाया गया है, ऐसा लगता है कि विशेषता आदेश को संरक्षित करता है और एक व्यवहार्य समाधान की तरह लगता है। किसी भी तरह से, मुझे लगता है कि यह एक अलग SO सवाल का हकदार है। –

+0

ठीक है .. विशेषताओं के शीर्ष पर, 'xml' भी निर्देश टैग को संसाधित करता है (उदा। '') और xmlns नेमस्पेस का नाम बदलता है। फिर, 'lxml' न तो करता है। –

संबंधित मुद्दे