2017-11-03 63 views
-1

私はPythonを初めて使いました。いくつかの規則でXMLを並べ替えようとしています。
私の例:PythonでXML要素を並べ替え、タグと属性を再帰的に並べ替え

<?xml version="1.0"?> 
<data> 
    <e2 id="3" name="name3"> 
     <e12 num="num12" desc="desc12"/> 
     <e12 num="num12" desc="desc11"/> 
     <e11 num="num1" desc="desc1"/> 
    </e2> 
    <e2 id="2" name="name2"> 
     <e11 num="num1" desc="desc1"/> 
    </e2> 
    <e1 id="1" name="name1"> 
     <e12 num="num12" desc="desc12"/> 
     <e11 num="num4" desc="desc4"/> 
    </e1> 
</data> 

私のルールは以下のとおりです。
1)それぞれの要素
2名でソートすべての属性)タグ名でソート要素
*(属性なしの場合)
* ifタグ属性の順序で同じ名前

私の場合、最初のe1とe2をソートする必要があります。
2つのe2要素があるため、属性名r 1つはid = 2、もう1つはid = 3なので、idの値で順序を決める必要があります。
所望の出力XMLは次のようになります。

<?xml version="1.0"?> 
<data> 
    <e1 id="1" name="name1"> 
     <e11 desc="desc4" num="num4"/> 
     <e12 desc="desc12" num="num12"/> 
    </e1> 
    <e2 id="2" name="name2"> 
     <e11 desc="desc1" num="num1"/> 
    </e2> 
    <e2 id="3" name="name3"> 
     <e11 num="num1" desc="desc1"/> 
     <e12 desc="desc11" num="num12"/> 
     <e12 desc="desc12" num="num12"/> 
    </e2> 
</data> 

何かアドバイスやアイデアはどのようにこれを行うには?
ありがとうございます。

答えて

1

ElementTreeを使用してXMLを並べ替えることができます。私の例では、私はattributの「name」の値と、タグ名とattribut「DESC」の値によって、子要素によって、タグ名と第二で最初

import xml.etree.ElementTree as ET 
tree = ET.ElementTree(ET.fromstring(xmlstr)) 
root = tree.getroot() 

# sort the first layer 
root[:] = sorted(root, key=lambda child: (child.tag,child.get('name'))) 

# sort the second layer 
for c in root: 
    c[:] = sorted(c, key=lambda child: (child.tag,child.get('desc'))) 

xmlstr = ET.tostring(root, encoding="utf-8", method="xml") 
print(xmlstr.decode("utf-8")) 

を、それを並べ替えるこれは

を印刷します
<data> 
<e1 id="1" name="name1"> 
    <e11 desc="desc4" num="num4" /> 
    <e12 desc="desc12" num="num12" /> 
</e1> 
<e2 id="2" name="name2"> 
    <e11 desc="desc1" num="num1" /> 
</e2> 
<e2 id="3" name="name3"> 
    <e11 desc="desc1" num="num1" /> 
    <e12 desc="desc11" num="num12" /> 
    <e12 desc="desc12" num="num12" /> 
</e2> 
</data> 
+0

ありがとうございます...私はこの例をダイナミックソートに使用できます。属性は同じタイプの要素に対して変更できるためです。 – Deniz

1

xml.etree.ElementTreeオブジェクトと溶液:

import xml.etree.ElementTree as ET 

tree = ET.parse('input.xml') 
data = tree.getroot() 
els = data.findall("*[@id]") # all e<number> elements having `id` attribute 
new_els = sorted(els, key=lambda el: (el.tag, el.attrib['id'])) 
for el in new_els: 
    el[:] = sorted(el, key=lambda e: (e.tag, e.attrib['desc'])) 
data[:] = new_els 

tree.write('result.xml', xml_declaration=True, encoding='utf-8') 

最終result.xml conten ts:

<?xml version='1.0' encoding='utf-8'?> 
<data> 
    <e1 id="1" name="name1"> 
     <e11 desc="desc4" num="num4" /> 
    <e12 desc="desc12" num="num12" /> 
     </e1> 
<e2 id="2" name="name2"> 
     <e11 desc="desc1" num="num1" /> 
    </e2> 
    <e2 id="3" name="name3"> 
     <e11 desc="desc1" num="num1" /> 
    <e12 desc="desc11" num="num12" /> 
     <e12 desc="desc12" num="num12" /> 
     </e2> 
    </data> 
+0

これは、2番目のe2チャイルドをソートしません。 e11 - > e12 ... – Deniz

+1

@Deniz、はい、私の更新を参照してください – RomanPerekhrest

+1

これはまた、うまく動作していただきありがとうありがとう、両方の答えが正しいです。 – Deniz

関連する問題