如何使用xslt比较和合并两个xml
我想比较两个XML,然后合并它们。例如: myFile1.xml如何使用xslt比较和合并两个xml,xml,xslt,merge,Xml,Xslt,Merge,我想比较两个XML,然后合并它们。例如: myFile1.xml <?xml version="1.0" encoding="ISO-8859-1"?> <catalog> <data> <title>Title1</title> <description>Description1</description> <myid>1</myid> </data>
<?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>
标题1
说明1
1.
标题2
说明2
2.
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>
标题1
说明1
作者1
12/34/5678
1.
作者2
87/65/4321
2.
期望输出:
<?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>
标题1
说明1
1.
作者1
12/34/5678
标题2
说明2
2.
作者2
87/65/4321
我有一个代码,但它没有按照要求的输出执行
<?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>
请帮忙 此解决方案完全没有循环或键。我使用
document()
只加载了一个文档,而我使用另一个作为源。简单地说,源文档中缺少一个元素,它被加载到加载的文档中。此解决方案包含的元素越多,可用性越低。请参阅底部以了解更一般的信息
XSLT1.0在萨克森HE 9.2.1.1J上测试
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="catalog2" select="document('source_test2.xml')/catalog"/>
<xsl:template match="catalog">
<catalog>
<xsl:apply-templates select="data"/>
</catalog>
</xsl:template>
<xsl:template match="data">
<xsl:variable name="data2" select="$catalog2/data[myid=current()/myid]/."/>
<data>
<xsl:choose>
<xsl:when test="title">
<xsl:copy-of select="title"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$data2/title"/>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="description">
<xsl:copy-of select="description"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$data2/description"/>
</xsl:otherwise>
</xsl:choose>
<xsl:copy-of select="myid"/>
<xsl:choose>
<xsl:when test="author">
<xsl:copy-of select="author"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$data2/author"/>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="date">
<xsl:copy-of select="date"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$data2/date"/>
</xsl:otherwise>
</xsl:choose>
</data>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="catalog2" select="document('myFile2.xml')/catalog"/>
<xsl:template match="catalog">
<catalog>
<xsl:apply-templates select="data"/>
</catalog>
</xsl:template>
<xsl:template match="data">
<xsl:variable name="data1" select="."/>
<xsl:variable name="data2" select="$catalog2/data[myid=current()/myid]/."/>
<data>
<xsl:copy-of select="$data1/*"/>
<xsl:for-each select="$data2/*">
<xsl:variable name="element2" select="name(.)"/>
<xsl:if test="count($data1/*[name()=$element2])=0">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</data>
</xsl:template>
</xsl:stylesheet>
如何匹配两个文档之间的节点?就凭他们的立场?我是说doc1上的第一个节点必须与doc2上的第一个节点合并?或者通过
myid
?不,它与myid
匹配,而不是通过它们的位置。如果您只是更改
字段的顺序,那么它将相应地从第二个文档中复制字段。我明白了,我正在尝试与您不同的方法。也许你会看到我的答案。是的,当然。事实上,我是xslt新手,所以我想不出任何其他方法。任何有效的方法都会很受欢迎。现在看看我的答案。我做了一些测试,它看起来很有效。感谢您的快速响应,但这将是一个特定于模式的测试,对吗?如果我有一个包含1000多个元素的大型模式呢。那么这将不是一个可行的方法。如果我错了,请纠正我。是的,您拥有的元素越多,这种方法的可用性就越差。但我无法找到另一种方法。可能在接下来的几天。如果你找到一个解决方案,请把它贴在这里作为答案。我已经添加了一个更通用的解决方案。请注意,在某些情况下,元素顺序可能会受到影响。这很难解决,因为您的假设不知道源模式。希望这对你有帮助。我想这可能有用。实际上,源模式非常庞大。我将不得不做一些修改,但这可以工作。谢谢。一旦我得到结果,我会告诉你的。是的,到目前为止,这一切都很顺利。非常感谢您提供的解决方案,如果我有任何进一步的问题,我们将通知您。再次感谢。