2016-10-20 23 views
0

子供の名前の「ルート」タグが多数あります。私は、 '名前'要素のアルファベット順に並べられた 'ルート'ブロックをソートしたい。 lxml/etree/minidomを試しましたが、うまく動作しません... タグ内の値を解析して親ルートタグをソートすることはできません。私は変数からの読み取り、画面にdumpinてる子要素によるXMLタグの並べ替えPython

import xml.etree.ElementTree as ET 


xml="<?xml version='1.0' encoding='UTF-8'?><roots><root><path>//1.1.1.100/Alex</path><name>Alex Space</name></root><root><path>//1.1.1.101/Steve</path><name>Steve Space</name></root><root><path>//1.1.1.150/Bethany</path><name>Bethanys</name></root></roots>" 
oldxml = ET.fromstring(xml) 

names = [] 
for rootobj in oldxml.findall('root'): 
    names.append(rootobj.find('name').text) 

newxml = ET.Element('roots') 
for name in sorted(names): 
    for rootobj in oldxml.findall('root'): 
     if name == rootobj.find('name').text: 
      newxml.append(rootobj) 
ET.dump(oldxml) 
ET.dump(newxml) 

import xml.etree.ElementTree as ET 

    def sortchildrenby(parent, child): 
     parent[:] = sorted(parent, key=lambda child: child) 


tree = ET.parse('data.xml') 
root = tree.getroot() 

sortchildrenby(root, 'name') 
for child in root: 
    sortchildrenby(child, 'name') 


tree.write('output.xml') 
+0

名前が最初に来るようにしますか? –

答えて

1

あなたが最初名前ノード入れたい場合:

あなたを与えるだろう
x = """ 
    <roots> 
    <root> 
     <path>//1.1.1.100/Alex</path> 
     <name>Alex Space</name> 
    </root> 
    <root> 
     <path>//1.1.1.101/Steve</path> 
      <name>Bethanys</name> 
    </root> 
    <root> 
     <path>//1.1.1.150/Bethany</path> 
     <name>Steve Space</name> 
    </root> 
</roots>""" 

import lxml.etree as et 
tree = et.fromstring(x) 

for r in tree.iter("root"): 
    r[:] = sorted(r, key=lambda ch: -(ch.tag == "name")) 

print(et.tostring(tree).decode("utf-8")) 

を:

<roots> 
    <root> 
     <name>Alex Space</name> 
    <path>//1.1.1.100/Alex</path> 
     </root> 
    <root> 
     <name>Bethanys</name> 
    <path>//1.1.1.101/Steve</path> 
      </root> 
    <root> 
     <name>Steve Space</name> 
    <path>//1.1.1.150/Bethany</path> 
     </root> 
</roots> 

しかし、あなたは単に最初にそれらを追加したい場合はソートする必要はありません名前を削除してインデックス0に再挿入するだけでよい:

のノードがソートされた順序で、実際にはありません、あなたはアルファベット順にノードを再配置する場合:

あなたを与えるだろう
x = """ 
    <roots> 
    <root> 
     <path>//1.1.1.100/Alex</path> 
     <name>Alex Space</name> 
    </root> 
    <root> 
     <path>//1.1.1.101/Steve</path> 
     <name>Steve Space</name> 
    </root> 
    <root> 
     <path>//1.1.1.150/Bethany</path> 
     <name>Bethanys</name> 
    </root> 
</roots>""" 
import lxml.etree as et 
tree = et.fromstring(x) 

tree[:] = sorted(tree, key=lambda ch: ch.xpath("name/text()")) 

print(et.tostring(tree).decode("utf-8")) 

<roots> 
    <root> 
     <path>//1.1.1.100/Alex</path> 
     <name>Alex Space</name> 
    </root> 
    <root> 
     <path>//1.1.1.150/Bethany</path> 
     <name>Bethanys</name> 
    </root> 
    <root> 
     <path>//1.1.1.101/Steve</path> 
     <name>Steve Space</name> 
    </root> 
</roots> 

ます。また、最初のいずれかと組み合わせることができます2つのアプローチ2は、ルートノードを最初に配置するノードを再配置します。

+0

最後に提案したのは、ありがとうございました – bzzWomp

+0

あなたの入力が既にソートされているようには思えませんでしたが、実際にはソートされていないファイルの出力が期待されていたと思います。 –

-1

はこれを試してみてください:ここで

<?xml version='1.0' encoding='UTF-8'?> 
    <roots> 
    <root> 
     <path>//1.1.1.100/Alex</path> 
     <name>Alex Space</name> 
    </root> 
    <root> 
     <path>//1.1.1.101/Steve</path> 
     <name>Steve Space</name> 
    </root> 
    <root> 
     <path>//1.1.1.150/Bethany</path> 
     <name>Bethanys</name> 
    </root> 
</roots> 

は、私がしようとしているものです。

ファイルから読み込みを変更し、必要に応じてファイルにダンプできます。

関連する問題