2012-07-23 101 views
1

是否有可能XML文件,如排序如下:排序XML文件

<model name="ford"> 
<driver>Bob</driver> 
<driver>Alice</driver> 
</model> 

<model name="audi"> 
<driver>Carly</driver> 
<driver>Dean</driver> 
</model> 

這將成爲

<model name="audi"> 
<driver>Carly</driver> 
<driver>Dean</driver> 
</model> 

<model name="ford"> 
<driver>Alice</driver> 
<driver>Bob</driver> 
</model> 

也就是說,最外層的元素會先被排序,然後是第二最外面,和等等。

他們需要先按元素名稱排序。這可以做到嗎?或者我應該使用像BeautifulSoup這樣的東西來旋轉我自己的東西?

+1

將結構讀入對象列表中,對其進行排序,然後將其寫回到任意位置。就這麼簡單。我不認爲這裏的人會爲你寫代碼。 – MMM 2012-07-23 10:34:28

+0

我希望能有這樣的東西。這將節省重新發明輪子。 – Rory 2012-07-23 10:35:00

+1

對xml進行排序沒有意義,但可以使用xslt對其進行轉換。 [看到這個](http://www.w3schools.com/xsl/xsl_sort.asp) – Takahiro 2012-07-23 10:35:37

回答

4

這是基里爾的解決方案的改進,我認爲它能更好地反映規定的要求,並避免了錯誤類型XSLT 2.0將會給你,如果排序關鍵字包含多個值(但它仍然適用於1.0)。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" /> 

    <xsl:template match="*"> 
    <xsl:copy> 
    <xsl:copy-of select="@*"/> 
    <xsl:apply-templates select="*"> 
     <xsl:sort select="(@name | text())[1]"/> 
    </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+0

嗨,xslt中是否有拼寫錯誤:需要成爲起始標記,而不是完整標記(匹配的結束標記在文件中較低兩行) – 2016-02-11 11:49:38

+0

已修復。 ----------- – 2016-02-11 21:22:35

1

試試這個XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" /> 

    <xsl:template match="@* | node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@* | node()"> 
     <xsl:sort select="text() | @*"/> 
     </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 
+2

它的工作原理,但只是偶然,看起來比它更普遍。例如,它僅適用於具有子元素的元素只有一個屬性。 – 2012-07-23 11:08:21

0

你並不需要梳理整個XML DOM。 而是將所需的節點放入列表中並對其進行排序。因爲在處理時我們需要排序的順序,而不是在文件中,所以在運行時更好。 可能是這樣的,使用minidom。

import os, sys 
from xml.dom import minidom 
document = """\ 
<root> 
<model name="ford"> 
<driver>Bob</driver> 
<driver>Alice</driver> 
</model><model name="audi"> 
<driver>Carly</driver> 
<driver>Dean</driver> 
</model> 
</root> 
""" 

document = minidom.parseString(document) 
elements = document.getElementsByTagName("model") 
elements.sort(key=lambda elements:elements.attributes['name']) 
0

您可以通過將節點從父節點中刪除並按照預定順序重新插入節點來排序節點。例如:

def sort_tree(tree): 
    """ recursively sorts the given etree in place """ 
    for child in tree: 
     sort_tree(child) 

    sorted_children = sorted(tree, key=lambda n: n.text) 
    for child in tree: 
     tree.remove(child) 
    for child in reversed(sorted_children): 
     tree.insert(0, child) 

tree = etree.fromstring(YOUR_XML) 
sort_tree(tree) 
print(etree.tostring(tree, pretty_print=True))