[英]how to compare and merge two xml using xslt
我想比較兩個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()
加載了一個文檔,而另一個文檔則作為源加載。 簡而言之,源文檔中缺少一個元素,它是在加載的元素上獲取的。 更多可用的元素就是這個解決方案。 請參閱底部以獲得更一般的信息。
XSLT 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>
以下是更通用的解決方案。 方法是一樣的。 對於每個data
,存在於一個元件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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.