2014-01-15 42 views
1

我有兩個XML的文件與此類似:XSLT - 比較兩個文件similarXML

1.

<data> 
    <object ID="1"> 
     <ID>1</ID> 
     <name>abc</name> 
     <weight>50</weight> 
    </object> 
    <object ID="2"> 
     <ID>2</ID> 
     <name>def</name> 
     <weight>75</weight> 
    </object> 
</data> 

2.

<data> 
    <object ID="2"> 
     <ID>2</ID> 
     <name>def</name> 
     <weight>75</weight> 
    </object> 
    <object ID="3"> 
     <ID>3</ID> 
     <name>ghi</name> 
     <weight>100</weight> 
    </object> 
</data> 

,現在我想對它們進行比較。可以使用其他元素(類似兩者)或新文件(in_both_files.xml,only_in_file1.xml,only_in_file2.xml)。我知道,XSLT不是最適合此任務的,我錯過了PHP/SQL ... 解決此問題的最佳方法是什麼? 我已經在尋找解決方案,但大多數人似乎很樂意合併它。 我的想法是給每個對象的ID作爲attribut,然後通過第一個文件,並使用document()和key()在另一個文件中查找相同的對象。這是好的還是可能的?現在沒有工作,我不知道,這是否是正確的方法。

編輯: 這是一個評估。一個XML文件是我們擁有的對象,根據系統和另一個XML文件確實在倉庫中。因此,如果一個對象出現在兩個列表中,它們具有絕對相同的ID,名稱,重量等。但是ID是唯一的,這對每個對象都是絕對唯一的(但當然應該在兩個文件中)。所以我需要知道,哪些對象在倉庫中,但不在系統中,因此我可以導入它們,哪些在系統中,但不在倉庫中,因此必須標記爲「丟失」。

所以只要將它們合併,將不利於...

一個結果像

only_in_system.xml 
<data> 
    <object> 
     <ID>1</ID> 
     <name>abc</name> 
     <weight>50</weight> 
    </object> 
</data> 

only_in_depot.xml 
<data> 
    <object> 
     <ID>3</ID> 
     <name>ghi</name> 
     <weight>100</weight> 
    </object> 
</data> 

(additional) everything_is_ok.xml 
<data> 
    <object> 
     <ID>2</ID> 
     <name>def</name> 
     <weight>75</weight> 
    </object> 
</data> 

就好了!還有更多的個人轉換可以連續使用(我認爲必須)!

+0

合併是否爲對象ID 2不重複的文件? –

+0

你能定義這種比較的確切規則嗎?如果只檢查在file1/file2 /兩者中是否存在具有相同''的'',而不考慮對象的內容(ID元素除外),則這不應該太難實現,我認爲。 –

回答

4

所以,如果一個物體在兩個列表中出現,他們有絕對相同的 ID,名稱,重量等

那好吧,那真的會讓人很簡單:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> 

<xsl:variable name="file2" select="document('file2.xml')" /> 

<xsl:variable name="IDs1" select="/data/object/ID" /> 
<xsl:variable name="IDs2" select="$file2/data/object/ID" /> 

<xsl:template match="/data"> 
<result> 
    <data desc="only in file1"> 
     <xsl:apply-templates select="object[not(ID=$IDs2)]"/> 
    </data> 
    <data desc="only in file2"> 
     <xsl:apply-templates select="$file2/data/object[not(ID=$IDs1)]"/> 
    </data> 
    <data desc="in both files"> 
     <xsl:apply-templates select="object[ID=$IDs2]"/> 
    </data> 
</result> 
</xsl:template> 

<xsl:template match="object"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

</xsl:stylesheet>