2009-03-19 12 views
10

के साथ संशोधित करते समय विशेषताओं के क्रम को सुरक्षित रखें क्या कोई तरीका है कि मैं मिनीडॉम के साथ एक्सएमएल प्रोसेस करते समय गुणों के मूल क्रम को संरक्षित कर सकता हूं?मिनीडॉम

कहें कि मेरे पास है: <color red="255" green="255" blue="233" /> जब मैं इसे मिनीडॉम के साथ संशोधित करता हूं तो गुणों को वर्णानुक्रमिक नीले, हरे और लाल रंग में पुन: व्यवस्थित किया जाता है। मैं मूल आदेश को संरक्षित करना चाहता हूं।

मैं elements = doc.getElementsByTagName('color') द्वारा लौटाए गए तत्वों के माध्यम से फ़ाइल को प्रोसेस कर रहा हूं और फिर मैं इस e.attributes["red"].value = "233" जैसे असाइनमेंट करता हूं।

उत्तर

8

क्या कोई तरीका है कि मैं मिनीडॉम के साथ एक्सएमएल प्रोसेस करते समय गुणों के मूल क्रम को संरक्षित कर सकता हूं?

मिनीडोम संख्या के साथ, गुणों को स्टोर करने के लिए उपयोग की जाने वाली डेटाटाइप एक असाधारण शब्दकोश है। pxdom ऐसा कर सकता है, हालांकि यह काफी धीमी है।

-1

मैं minidom के बजाय lxml लाइब्रेरी का उपयोग कर समाप्त हो गया है।

+1

उदाहरण के लिए, देखें [इस पोस्ट] (http: // stackoverflow। कॉम/ए/34560411/540510) – thdox

3

यह स्पष्ट है कि xml विशेषता का आदेश नहीं दिया गया है। मुझे अभी यह अजीब व्यवहार मिला है!

ऐसा लगता है कि यह xml.dom.minidom.Element.writexml फ़ंक्शन में जोड़े गए सॉर्ट से संबंधित है !!

class Element(Node): 
... snip ... 

    def writexml(self, writer, indent="", addindent="", newl=""): 
     # indent = current indentation 
     # addindent = indentation to add to higher levels 
     # newl = newline string 
     writer.write(indent+"<" + self.tagName) 

     attrs = self._get_attributes() 
     a_names = attrs.keys() 
     a_names.sort() 
--------^^^^^^^^^^^^^^ 
     for a_name in a_names: 
      writer.write(" %s=\"" % a_name) 
      _write_data(writer, attrs[a_name].value) 
      writer.write("\"") 

लाइन को हटाने से एक दस्तावेज़ को पुनर्स्थापित किया जाता है जो मूल दस्तावेज़ का क्रम रखता है। यह एक अच्छा विचार है जब आपको diff टूल के साथ जांच करनी होती है कि आपके कोड में कोई गलती नहीं है।

from collections import OrderedDict 

तत्व वर्ग में:

8

विशेषता आदेश मैं minidom में इस मामूली संशोधन किए गए रखने के लिए अब

__init__(...) 
    self._attrs = OrderedDict() 
    #self._attrs = {} 
writexml(...) 
    #a_names.sort() 

यह केवल अजगर 2.7+ के साथ काम करेंगे और मैं कर रहा हूँ सुनिश्चित नहीं है कि यह वास्तव में काम करता है => अपने जोखिमों पर उपयोग करें ...

और कृपया ध्यान दें कि आपको विशेषता आदेश पर भरोसा नहीं करना चाहिए:

ध्यान दें कि स्टार्ट-टैग या खाली-तत्व टैग में विशेषता विनिर्देशों का क्रम महत्वपूर्ण नहीं है।

+0

आपने टी को कैसे संशोधित किया वह तत्व वर्ग? – NPike

+0

अभी भी पायथन 3.2 पर काम करता है, 'a_names = sorted (attrs.keys()) ''__name = attrs.keys()' –

3

अजगर 2.7 से पहले, मैं HotPatching निम्नलिखित का इस्तेमाल किया:

class _MinidomHooker(object): 
    def __enter__(self): 
     minidom.NamedNodeMap.keys_orig = minidom.NamedNodeMap.keys 
     minidom.NamedNodeMap.keys = self._NamedNodeMap_keys_hook 
     return self 

    def __exit__(self, *args): 
     minidom.NamedNodeMap.keys = minidom.NamedNodeMap.keys_orig 
     del minidom.NamedNodeMap.keys_orig 

    @staticmethod 
    def _NamedNodeMap_keys_hook(node_map): 
     class OrderPreservingList(list): 
      def sort(self): 
       pass 
     return OrderPreservingList(node_map.keys_orig()) 

इस तरह से उपयोग किया:

with _MinidomHooker(): 
    document.writexml(...) 

अस्वीकरण:

  1. तू के आदेश पर भरोसा नहीं करेगा जिम्मेदार बताते हैं।
  2. NamedNodeMap वर्ग को म्यूट करना सुरक्षित नहीं है।
  3. हॉटपैचिंग बुरा है।
2

आप लोग जितने चाहें उतने अस्वीकरण कर सकते हैं। गुणों को पुन: व्यवस्थित करते समय प्रोग्राम के लिए कोई अर्थ नहीं है, इसका प्रोग्रामर/उपयोगकर्ता के लिए कोई अर्थ है।

फ्रेडरिक के लिए आरजीबी आदेश होना महत्वपूर्ण था क्योंकि रंगों का क्रम है। मेरे लिए यह विशेष रूप से नाम विशेषता है।

<field name="url" type="string" indexed="true" stored="true" required="true" multiValued="false"/> <!-- ID --> 
<field name="forkortelse" type="string" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="kortform" type="text_general" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="dato" type="date" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="nummer" type="int" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="kilde" type="string" indexed="true" stored="true" required="false" multiValued="false" /> 
<field name="tittel" type="text_general" indexed="true" stored="true" multiValued="true"/> 

की तुलना के खिलाफ

<field indexed="true" multiValued="false" name="forkortelse" required="false" stored="true" type="string"/> 
<field indexed="true" multiValued="false" name="kortform" required="false" stored="true" type="text_general"/> 
<field indexed="true" multiValued="false" name="dato" required="false" stored="true" type="date"/> 
<field indexed="true" multiValued="false" name="nummer" required="false" stored="true" type="int"/> 
<field indexed="true" multiValued="false" name="kilde" required="false" stored="true" type="string"/> 
<field an_optional_attr="OMG!" an_optional_attr2="OMG!!" indexed="true" name="tittel" stored="true" type="text_general"/> 

हालांकि यह असंभव नहीं है, यह के रूप में आसान नहीं है पढ़ने के लिए। नाम महत्वपूर्ण विशेषता है। नाम फ़ील्ड के रास्ते को छिपाना अच्छा नहीं है। क्या होगा यदि नाम बाईं ओर 15 विशेषताएँ था जहां सामने के 7 गुण वैकल्पिक थे?

बिंदु यह है कि पुनर्वितरण एक बड़ी समस्या है जो आवक क्रम में देता है। यह प्रोग्रामर सोचता है या कार्यक्षमता कैसे काम करने के तरीके के साथ गड़बड़ है। कम से कम ऑर्डरिंग कॉन्फ़िगर करने योग्य/वैकल्पिक होनी चाहिए।

मेरी खराब अंग्रेजी क्षमा करें। यह मेरी मुख्य भाषा नहीं है।

+3

द्वारा प्रतिस्थापित करें जो आप यहां कह रहे हैं वह अनुचित नहीं है। लेकिन यह सवाल का जवाब नहीं है। – mzjn

+0

मुझे समझ में नहीं आता –

+0

मैं जो कह रहा हूं उससे पूरी तरह से सहमत हूं, लेकिन यह वास्तव में एक टिप्पणी होनी चाहिए, भले ही यह एक के लिए बहुत बड़ा हो। –

1

1. अपनी खुद की 'Element.writexml' विधि बनाएं।

'minidom.py' कॉपी से एलिमेंट के writexml कोड को अपनी फ़ाइल में कॉपी करें।

यह writexml_nosort को नाम बदलने,

हटाएँ 'a_names.sort()' (अजगर 2.7) या परिवर्तन 'a_names = अनुसार क्रमबद्ध (attrs.keys())' को 'a_names = attrs.keys()' (अजगर 3,4)

परिवर्तन अपने स्वयं के तत्व की विधि:

minidom.Element.writexml = writexml_nosort;

2. कस्टम अपने पसंदीदा क्रम:

right_order = [ 'एक', 'बी', 'सी', 'a1', 'बी 1']

अपने तत्व 3.adjust के _attrs

node._attrs = ([right_order में कश्मीर के लिए (के, node._attrs [k])]) OrderedDict