2016-09-24 97 views
-1

我試圖比較兩個具有相同內容但時間不同的行的XML文件。爲了克服這個問題,我試圖對其中一個子節點(通常在兩個文件中的位置不同)上的XML進行排序。基於節點值排序XML文件

這裏是我的示例XML文件

<Report> 
<rptName>Sample</rptName> 
<reportNameGrp> 
<grpName>AggrDataSet</grpName> 
<RC> 
<rptSubHdr> 
<membLglNam>Registered Customer 103</membLglNam> 
<membId>RC103</membId> 
<relCM>CM022</relCM> 
</rptSubHdr> 
</RC> 
<RC> 
<rptSubHdr> 
<membLglNam>Registered Customer 055</membLglNam> 
<membId>RC055</membId> 
<relCM>CM022</relCM> 
</rptSubHdr> 
</RC> 
<RC> 
<rptSubHdr> 
<membLglNam>Registered Customer 047</membLglNam> 
<membId>RC047</membId> 
<relCM>CM022</relCM> 
</rptSubHdr> 
</RC> 
<RC> 
<rptSubHdr> 
<membLglNam>Registered Customer 015</membLglNam> 
<membId>RC015</membId> 
<relCM>CM022</relCM> 
</rptSubHdr> 
</RC> 
<RC> 
<rptSubHdr> 
<membLglNam>Registered Customer 024</membLglNam> 
<membId>RC024</membId> 
<relCM>CM022</relCM> 
</rptSubHdr> 
</RC> 
</reportNameGrp> 
</Report> 

我想基於對<RC>父節點<membId>節點進行排序。無論我嘗試什麼方法,我的文檔都無法排序。我嘗試過使用XSLT,但排序不起作用。我甚至嘗試編寫一個Python腳本,但它無法排序。

這裏是我的Python腳本 -

import sys 
from lxml import etree 

filename, tag = sys.argv[1:] 

doc = etree.parse(filename, etree.XMLParser(remove_blank_text=True)) 
root = doc.getroot() 
root[:] = sorted(root, key=lambda el: el.findtext(tag)) 
print etree.tostring(doc, pretty_print=True) 

我執行python test.py 2.xml membId運行腳本(請注意,2.XML是XML輸入文件名和membId是我一直在尋找的標籤)。

我真的很感謝在我出錯的地方提供任何幫助。我剛剛開始使用Python,所以我可能犯了一個非常明顯的錯誤。一個python腳本或XSLT解決方案(或者)將爲我工作!

+2

** ** 1「*我嘗試使用XSLT,但排序沒有。工作。*「請張貼您的嘗試,以便我們可以修復它,而不是從頭開始爲您編寫代碼。 - ** 2。**當你在它的時候,也發佈期望的輸出,因爲「*基於節點對​​父節點*進行排序」是一個相當神祕的要求。 - ** 3。**爲什麼您的問題被標記爲「XSLT 2.0」?你實際上使用的是支持XSLT 2.0的處理器嗎? –

+1

Python的lxml僅支持使用libxslt處理器的XSLT 1.0。 – Parfait

+0

@ michael.hor257k我將在XSLT尋求幫助的同時發佈另一個問題。是的,我使用XSLT2.0,這就是爲什麼我這樣標記它。 – Incognito

回答

2

請考慮使用Python的lxml集成的以下XSLT腳本。此外,您嘗試運行動態命令行進程。不幸的是,XSLT將根據您打算分類的特定節點而在結構上發生變化。下面將具體排序<membId>按升序排列:

XSLT

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output version="1.0" encoding="UTF-8" indent="yes" /> 
<xsl:strip-space elements="*"/> 

    <!-- Identity Transform --> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- Sort MembId under RC/rptSubHdr --> 
    <xsl:template match="reportNameGrp"> 
    <xsl:copy>  
     <xsl:copy-of select="grpName"/> 
     <xsl:apply-templates select="RC">   
      <xsl:sort select="rptSubHdr/membId" order="ascending"/> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

</xsl:transform> 

的Python

import lxml.etree as et 

// LOAD XML AND XSL SOURCES 
dom = et.parse('Input.xml') 
xslt = et.parse('XSLTScript.xsl') 

// TRANSFORM 
transform = et.XSLT(xslt) 
newdom = transform(dom) 

// SAVE TO FILE 
with open('Output.xml', 'wb') as f: 
    f.write(newdom) 
+0

這將放棄'grpName'元素。 –

+0

謝謝!它可以幫助我給出方向,但不能真正解決問題。我想我只會用我遇到的XSLT發佈另一個問題,以便我可以獲得幫助。 – Incognito

+0

這是什麼問題?你的問題標題和文本提到了按照這個答案的節點排序XML值。請詳細描述所需的輸出。此外,XSLT 1.0甚至可以使用[document()](http://www.w3schools.com/xsl/func_document.asp)從其他文件解析。 – Parfait