2011-12-05 18 views
6

मेरे पास एक विरासत फ़ाइल प्रारूप है जिसे मैं प्रोसेसिंग के लिए एक्सएमएल में परिवर्तित कर रहा हूं। संरचना में संक्षेप किया जा सकता है के रूप में:एलएक्सएमएल - सॉर्टिंग टैग ऑर्डर

<A> 
    <A01>X</A01> 
    <A02>Y</A02> 
    <A03>Z</A03> 
</A> 

टैग की संख्यात्मक हिस्सा 01 से 99 तक जा सकते हैं और वहाँ अंतराल हो सकता है। प्रसंस्करण के हिस्से के रूप में कुछ रिकॉर्ड में अतिरिक्त टैग जोड़े जा सकते हैं। प्रसंस्करण पूरा होने के बाद मैं पेड़ को घुमाकर फ़ाइल को वापस विरासत प्रारूप में परिवर्तित कर रहा हूं। फाइलें काफी बड़े हैं (~ 150,000 नोड्स)।

इस समस्या में यह है कि विरासत प्रारूप का उपयोग करने वाले कुछ सॉफ़्टवेयर मानते हैं कि टैग (या इसके बदले में फ़ील्ड अल्फा-न्यूमेरिक ऑर्डर में होंगे लेकिन डिफ़ॉल्ट रूप से नए टैग अंत में जोड़े जाएंगे शाखा जो तब उन्हें गलत क्रम में पुनरावर्तक से बाहर आने का कारण बनती है।

मैं प्रत्येक बार एक नया टैग जोड़ने के लिए टैग नाम के आधार पर पूर्ववर्ती भाई को ढूंढने के लिए xpath का उपयोग कर सकता हूं लेकिन मेरा सवाल यह है कि क्या निर्यात से पहले एक बार पेड़ को सॉर्ट करने का एक आसान तरीका है?

संपादित करें:

मुझे लगता है कि संरचना में संक्षेप से अधिक मैंने।

<X> 
    <X01>1</X01> 
    <X02>2</X02> 
    <X03>3</X03> 
    <A> 
     <A01>X</A01> 
     <A02>Y</A02> 
     <A03>Z</A03> 
    </A> 
    <B> 
     <B01>Z</B02> 
     <B02>X</B02> 
     <B03>C</B03> 
    </B> 
</X> 
+2

मैं इतना यकीन है कि XML स्कीमा बहुत अच्छी तरह से के माध्यम से सोचा है नहीं कर रहा हूँ

यहाँ पूरे दस्तावेज़ भर में बच्चे तत्वों छँटाई की एक छोटी सी उदाहरण है। ए01 और ए 02 एक ही प्रकार की चीजें नहीं हैं? उन्हें एक ही तत्व का नाम साझा करना चाहिए। संख्या शायद एक विशेषता होनी चाहिए, टैग नाम का हिस्सा नहीं। साथ ही, टैग नामों की तुलना में अधिक पठनीय होना चाहिए, लेकिन मुझे एहसास है कि वे सिर्फ एक उदाहरण हो सकते हैं। –

+0

दुर्भाग्य से मैं विरासत प्रारूप का कोई नियंत्रण नहीं है और इस की यह कैसे कुंजी/मान जोड़े में डेटा संग्रहीत करता एक सीधा अनुवाद है। मूल फ़ाइल में यह "ए 01 = बॉब" कह सकता है और फिर अनुप्रयोगों को पता है कि संख्या का नाम है। – George

+0

एक्सएमएल में इसे लागू करने के कई तरीके हैं लेकिन जो आपने यहां दिखाया है वह बहुत ही अर्थपूर्ण अनुवाद नहीं है। आपकी स्कीमा जटिल और हमेशा-बदलती होगी। मैं सुझाव देता हूं कि ' मान 'जहां आइटम A01, A02 दर्शाता है। –

उत्तर

17

यह संभव है एक सहायक फू लिखने के लिए सही स्थान पर एक नया तत्व डालने के लिए nction, लेकिन संरचना के बारे में अधिक जानने के बिना इसे सामान्य बनाना मुश्किल है।

from lxml import etree 

data = """<X> 
    <X03>3</X03> 
    <X02>2</X02> 
    <A> 
     <A02>Y</A02> 
     <A01>X</A01> 
     <A03>Z</A03> 
    </A> 
    <X01>1</X01> 
    <B> 
     <B01>Z</B01> 
     <B02>X</B02> 
     <B03>C</B03> 
    </B> 
</X>""" 

doc = etree.XML(data,etree.XMLParser(remove_blank_text=True)) 

for parent in doc.xpath('//*[./*]'): # Search for parent elements 
    parent[:] = sorted(parent,key=lambda x: x.tag) 

print etree.tostring(doc,pretty_print=True) 

पैदावार:

<X> 
    <A> 
    <A01>X</A01> 
    <A02>Y</A02> 
    <A03>Z</A03> 
    </A> 
    <B> 
    <B01>Z</B01> 
    <B02>X</B02> 
    <B03>C</B03> 
    </B> 
    <X01>1</X01> 
    <X02>2</X02> 
    <X03>3</X03> 
</X> 
+0

धन्यवाद - लैम्बा फ़ंक्शन केवल वही करता है जो मुझे चाहिए। – George

+0

धन्यवाद ...मैंने ये आलेख भी उपयोगी पाया: http://wiki.python.org/moin/HowTo/Sorting http://www.secnetix.de/olli/Python/lambda_functions.hawk – Homer6

+0

मुझे समझ में नहीं आता कि आप 'माता-पिता का उपयोग क्यों करते हैं [:] = 'असाइनमेंट में। – Sdwdaw

4

आप इस तरह आप XML तत्वों सॉर्ट कर सकते हैं:

एक रिकॉर्ड कई स्तरों के रूप में ऊपर वर्णित की तरह कुछ देने के लिए शामिल कर सकते हैं

from operator import attrgetter 
from lxml import etree 

root = etree.parse(xmlfile) 
children = list(root) 
sorted_list = sorted(children, key=attrgetter('tag')) 

यदि यह चल रहा है बहुत धीमी गति से, तुम बस हो सकता है टैग नाम सॉर्ट और नोड का उपयोग कर xpath मिलती है:

tag_list = [item.tag for item in root] 
sorted_taglist = sorted(tag_list) 
संबंधित मुद्दे