xml - XSLT 合并两个 XML 文件
问题描述
我需要使用 XSLT 合并两个 XML 文件。转换发生在包含要合并的 XML 文件列表的 XML 文件上。
列表.xml
<?xml version="1.0" encoding="UTF-8" ?>
<files>
<file>..\src\main\resources\testOne.xml</file>
<file>..\src\main\resources\testTwo.xml</file>
</files>
这是我要合并的两个模板:
<xsl:template name="merge_nodes">
<xsl:param name="fnNewDeept"/>
<xsl:param name="snNewDeept"/>
<xsl:for-each select="$fnNewDeept">
<xsl:call-template name="merge_node">
<xsl:with-param name="first-node" select="$fnNewDeept"/>
<xsl:with-param name="second-node" select="$snNewDeept"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="merge_node">
<xsl:param name="first-node" />
<xsl:param name="second-node" />
<xsl:element name="{name(current())}">
<xsl:for-each select="$second-node/@*">
<xsl:copy/>
</xsl:for-each>
<xsl:if test="$first-node = '' and not(boolean($first-node/*) and boolean($second-node/*))">
<xsl:value-of select="$second-node"/>
</xsl:if>
<xsl:for-each select="$first-node/@*">
<xsl:copy/>
</xsl:for-each>
<xsl:if test="not(boolean($first-node/*) and boolean($second-node/*))">
<xsl:value-of select="$first-node"/>
</xsl:if>
<xsl:choose>
<xsl:when test="boolean($first-node/*) or boolean($second-node/*)">
<xsl:choose>
<xsl:when test="boolean($first-node/*/*)">
<xsl:call-template name="merge_nodes">
<xsl:with-param name="fnNewDeept" select="$first-node/*"/>
<xsl:with-param name="snNewDeept" select="$second-node/*"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
2. Value: <xsl:value-of select="current()/*"/>
2. Current: <xsl:value-of select="name(current()/*)"/>
2. First: <xsl:value-of select="name($first-node/*)"/>
2. Second: <xsl:value-of select="name($second-node/*)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
1. Value: <xsl:value-of select="current()"/>
1. Current: <xsl:value-of select="name(current())"/>
1. First: <xsl:value-of select="name($first-node)"/>
1. Second: <xsl:value-of select="name($second-node)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:template>
- Value、Current、First 和 Second 仅用于调试原因。
和我的两个 XML:
<?xml version="1.0" encoding="UTF-8" ?>
<first x="1">
<second param="wt" second="true">
<third>abc</third>
<third>def</third>
</second>
<fourth>
<fifth x="1">hij</fifth>
<fifth>klm</fifth>
</fourth>
<sixth>qrs</sixth>
</first>
2.
<?xml version="1.0" encoding="UTF-8" ?>
<first y="2">
<second param="123" second="false">
<third>asd</third>
<third>def</third>
</second>
<fourth>
<fifth y="2">tuv</fifth>
<fifth>wxy</fifth>
</fourth>
<sixth>678</sixth>
<sixth>910</sixth>
</first>
我希望第一个文件是首选文件,以便将第二个文件合并到第一个文件中。不应出现重复元素。
预期输出:
<?xml version="1.0" encoding="UTF-8" ?>
<first x="1" y="2">
<second param="wt" second="true">
<third>abc</third>
<third>def</third>
<third>asd</third>
</second>
<fourth>
<fifth x="1">hij</fifth>
<fifth>klm</fifth>
<fifth y="2">tuv</fifth>
<fifth>wxy</fifth>
</fourth>
<sixth>qrs</sixth>
<sixth>678</sixth>
<sixth>910</sixth>
</first>
我得到的输出:
<?xml version="1.0" encoding="windows-1252"?><first y="2" x="1">
<second param="wt" second="true">
2. Value: abc
2. Current: third
2. First: third
2. Second: third</second>
<fourth param="wt" second="true">
2. Value: hij
2. Current: fifth
2. First: third
2. Second: third</fourth>
<sixth param="wt" second="true">
2. Value:
2. Current:
2. First: third
2. Second: third</sixth>
</first>
我不知道如何同时沿着两棵树运行,所以我可以复制元素。有人有什么想法吗?我只能使用 Apaches XALAN。我使用最新的 2.7.2 版本。
编辑:由于已经存在误解。转换必须适用于类似的 XML 文件,这是大问题。
解决方案
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="doc" select="doc('merge2.xml')"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="first">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="$doc/first/@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="second">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
<xsl:copy-of select="$doc/first/second/third[ not(.= current()/third)]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="fourth">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
<xsl:copy-of select="$doc/first/fourth/fifth[ not(.= current()/fifth)]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="sixth">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
<xsl:copy-of select="$doc/first/sixth[ not(.= current()/sixth)]"/>
</xsl:template>
CHeck it
推荐阅读
- java - 将日期从 java 传递到 ireports 时出现异常
- sql - 如何获取按月排序的数据
- javascript - 为什么不能设置null显示的属性innerhtml
- .net - 此主机上安装了哪个 .NET 版本?
- keras - 在 Keras 中,在模型中使用 Lambda 时无法保存模型检查点。报错 ValueError: can only convert a array of size 1 to a Python scalar
- jquery - 单击复选框时禁用和启用 Jquery Button
- java - Kotlin 生成私有字段:@MyAnnotation 字段不能是私有或静态的
- javascript - 如何处理从父 Promise 链返回的具有各种可能结果的 Promise
- sql - 如何在oracle sql developer中获取用户的FID
- javascript - 如何在运行时跟踪 DIV 的子元素计数?