我想比较两个xmls然后合并它们.例如:
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>
请帮忙!
该解决方案完全没有循环或密钥.我只使用document()加载了一个文档,而另一个文档则作为源加载.简而言之,源文档中缺少一个元素,它是在加载的元素上获取的.更多可用的元素就是这个解决方案.请参阅底部以获得更一般的信息.
原文链接:https://www.f2er.com/xml/293058.htmlXSLT 1.0在Saxon-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>
以下是一个更通用的解决方案.方法是一样的.对于每个数据,myFile2中存在且myFile1中缺少的元素将添加到结果树中,反之亦然.
XSLT 1.0在Saxon-B 9.0.0.4J上测试
<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>