XSLT-比较两个相似的XML文件 [英] XSLT - Compare two similarXML files

查看:109
本文介绍了XSLT-比较两个相似的XML文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个与此类似的XML文件:



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作为属性,然后浏览第一个文件,并使用document()和key()在另一个文件中查找相同的对象。这样好/可能吗?到现在为止还没有工作,我不知道这是否是正确的方法。



编辑:
这是用于盘点。根据系统,一个XML文件是我们拥有的对象,另一个则是仓库中真正存在的对象。因此,如果一个对象同时出现在两个列表中,则它们具有完全相同的ID,名称,权重等。但是ID是唯一的事情,那就是每个对象都是绝对唯一的(但当然应该在两个文件中)。因此,我需要知道,哪些对象在软件仓库中,而不在系统中,所以我可以导入它们,哪些对象在系统中,但不在软件仓库中,因此必须标记为丢失。 / p>

因此,仅合并它们,将无济于事...



结果类似

  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>

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

太好了!

解决方案


因此,如果一个对象同时出现在两个列表中,则它们具有完全相同的
ID,名称,重量等。


好的,那真的很简单:

 <?xml version = 1.0 encoding = utf-8 ?> 
< xsl:stylesheet version = 1.0
xmlns:xsl = http://www.w3.org/1999/XSL/Transform>
< xsl:输出方法= xml版本= 1.0编码= utf-8 indent = yes />

< xsl:变量名称= file2 select = document(’file2.xml’) />

< xsl:变量名称= IDs1 select = /数据/对象/ ID />
< xsl:变量名= IDs2 select = $ file2 / data / object / ID />

< xsl:template match = / data>
< result>
< data desc =仅在file1中>
< xsl:apply-templates select = object [not(ID = $ IDs2)] />
< / data>
< data desc =仅在file2中>
< xsl:apply-templates select = $ file2 / data / object [not(ID = $ IDs1)] />
< / data>
< data desc =位于两个文件中>
< xsl:apply-templates select = object [ID = $ IDs2] />
< / data>
< / result>
< / xsl:template>

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

< / xsl:stylesheet>


I have two XML-files similar to this:

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>

And now I want to compare them. Either with an additional element (something like both) or a new files (in_both_files.xml, only_in_file1.xml, only_in_file2.xml). I know, XSLT is not the best for this quest, i am missing PHP/SQL... What would be the best way to solve this problem? I already searched for a solution, but most people seem to be happy to just merge it. My idea was to give every object the ID as attribut and then go through the first file and use document() and key() to look for the same object in the other file. Is this good/even possible? Didn't work by now, and i don't know, whether it's the right way.

Edit: This is for a stocktaking. One XML-file is the objects we have, according to the system and the other one what is really in the depot. So if one object appears on both lists, they have the absolute same ID, name, weight, etc. But the ID is the only thing, thats absolute uniquefor each object (but of course should be in both files). So I need to know, which object are in the depot but not in the system, so I can import them, and which ones are in the system, but not in the depot, and so have to be labeld as "lost".

So just merging them, won't help...

A result like

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>

would be nice! Also more individual transormations could be used (and i think, have to) in a row!

解决方案

So if one object appears on both lists, they have the absolute same ID, name, weight, etc.

Okay then, that really makes it rather simple:

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

这篇关于XSLT-比较两个相似的XML文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆