如何使用 xslt 比较和合并两个 xml
我想比较两个 xml,然后合并它们。例如:
myFile1.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<data>
<title>Title1</title>
<description>Description1</description>
<myid>1</myid>
</data>
<data>
<title>Title2</title>
<description>Description2</description>
<myid>2</myid>
</data>
</catalog>
myFile2.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<data>
<title>Title1</title>
<description>Description1</description>
<author>Author1</author>
<date>12/34/5678</date>
<myid>1</myid>
</data>
<data>
<author>Author2</author>
<date>87/65/4321</date>
<myid>2</myid>
</data>
</catalog>
所需的输出:
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<data>
<title>Title1</title>
<description>Description1</description>
<myid>1</myid>
<author>Author1</author>
<date>12/34/5678</date>
</data>
<data>
<title>Title2</title>
<description>Description2</description>
<myid>2</myid>
<author>Author2</author>
<date>87/65/4321</date>
</data>
</catalog>
我有一个代码,但是它没有按照所需的输出执行。
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
<xsl:variable name="compare" select="'myFile1.xml'"/>
<xsl:variable name="with" select="'myFile2.xml'"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:variable name="info1" select="document($compare)/catalog/data[myid=current()/myid]/."/>
<xsl:variable name="info2" select="document($with)/catalog/data[myid=current()/myid]/."/>
<xsl:for-each select="$info1/*">
<xsl:variable name="check1" select="name(current())"/>
<!--xsl:text>Current node1 : </xsl:text><xsl:value-of select="$check1"/-->
<xsl:for-each select="$info2/*">
<xsl:variable name="check2" select="name(current())"/>
<!--xsl:text>Current node2 : </xsl:text><xsl:value-of select="$check2"/-->
<xsl:if test="$check1!=$check2">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:transform>
请帮忙!
I want to compare two xmls and then merge them. For example:
myFile1.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<data>
<title>Title1</title>
<description>Description1</description>
<myid>1</myid>
</data>
<data>
<title>Title2</title>
<description>Description2</description>
<myid>2</myid>
</data>
</catalog>
myFile2.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<data>
<title>Title1</title>
<description>Description1</description>
<author>Author1</author>
<date>12/34/5678</date>
<myid>1</myid>
</data>
<data>
<author>Author2</author>
<date>87/65/4321</date>
<myid>2</myid>
</data>
</catalog>
Desired Output:
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<data>
<title>Title1</title>
<description>Description1</description>
<myid>1</myid>
<author>Author1</author>
<date>12/34/5678</date>
</data>
<data>
<title>Title2</title>
<description>Description2</description>
<myid>2</myid>
<author>Author2</author>
<date>87/65/4321</date>
</data>
</catalog>
I have a code but, it doesnot perform as per the required output.
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
<xsl:variable name="compare" select="'myFile1.xml'"/>
<xsl:variable name="with" select="'myFile2.xml'"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:variable name="info1" select="document($compare)/catalog/data[myid=current()/myid]/."/>
<xsl:variable name="info2" select="document($with)/catalog/data[myid=current()/myid]/."/>
<xsl:for-each select="$info1/*">
<xsl:variable name="check1" select="name(current())"/>
<!--xsl:text>Current node1 : </xsl:text><xsl:value-of select="$check1"/-->
<xsl:for-each select="$info2/*">
<xsl:variable name="check2" select="name(current())"/>
<!--xsl:text>Current node2 : </xsl:text><xsl:value-of select="$check2"/-->
<xsl:if test="$check1!=$check2">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:transform>
Please Help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
该解决方案完全没有循环或密钥。我仅使用
document()
加载了一个文档,而我使用另一个文档作为源。简而言之,源文档中缺少一个元素,它会在加载的文档中获取。元素越多,可用性就越差,这就是这个解决方案。请参阅底部以获得更通用的信息。XSLT 1.0 在 Saxon-HE 9.2.1.1J 上测试
下面是一个更通用的解决方案。方法是一样的。对于每个
data
,myFile2
中存在但myFile1
中缺失的元素将添加到结果树中,反之亦然。XSLT 1.0 在 Saxon-B 9.0.0.4J 上测试
This solution is totally free of loops or keys. I've loaded only one document using
document()
, while I use the other one as source. Briefly, an element missing in the source document, it is taken on the loaded one. More elements you have less usable is this solution. See bottom for a more general one.XSLT 1.0 tested on Saxon-HE 9.2.1.1J
Here follows a more general solution. The approach is the same. For each
data
, an element present inmyFile2
and missing inmyFile1
is added to the result tree, and vice-versa.XSLT 1.0 tested on Saxon-B 9.0.0.4J