2014-01-15 21 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>