2016-10-20 137 views
0

我有許多帶有子名稱的'root'標籤。我想對「根」塊進行排序,按「名稱」元素按字母順序排列。已嘗試過lxml/etree/minidom但無法正常工作... 我無法解析標籤中的值,然後對父根標籤進行排序。按子元素對XML標籤進行排序Python

<?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> 

這是我曾嘗試:

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:

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

for r in tree.iter("root"): 
    ch = r.find("name") 
    r.remove(ch) 
    r.insert(0, ch) 

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

如果節點實際上是不排序的順序,你想重新排列節點按字母順序:

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> 

您也可以結合使用或者第一兩個方法兩個也重新排列根節點節點放第一名。

+0

您的最終建議是我的目標,謝謝 – bzzWomp

+0

不用擔心,我不確定您的輸入是否已經排序,但我想這實際上是您的未排序文件的預期輸出。 –

-1

試試這個:

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) 

我從一個變量閱讀和dumpin它在屏幕上。

您可以將其從文件中讀取並將其轉儲到您需要的文件中。

相關問題