こういう用途ってないのかな??
saxonでしか確認してない。そもそも2.0でしか動かない!
call-templateはネストすると処理が重くなるため、apply-templatesで処理してます。
nodes1に放り込んだxmlに対して、nodes2を上書きしていきます。
要素の順番はnodes1側に引きづられ、nodes2側にしかない要素(追加したい要素)は兄弟要素として末尾に追加されます。
マージしたxmlに対してxpathで取得する際には問題が起きにくいですが、ノード番号等で取得するような場合は注意が必要です。
さて、次はドキュメント比較用のXSLTを作らねば・・・
call-templateはネストすると処理が重くなるため、apply-templatesで処理してます。
nodes1に放り込んだxmlに対して、nodes2を上書きしていきます。
要素の順番はnodes1側に引きづられ、nodes2側にしかない要素(追加したい要素)は兄弟要素として末尾に追加されます。
マージしたxmlに対してxpathで取得する際には問題が起きにくいですが、ノード番号等で取得するような場合は注意が必要です。
さて、次はドキュメント比較用のXSLTを作らねば・・・
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()" mode="marge">
<xsl:param name="nodes1" as="item()*" />
<xsl:param name="nodes2" as="item()*" />
<xsl:variable name="node1" select="$nodes1[1]" as="item()*" />
<xsl:variable name="node2" as="item()*">
<xsl:choose>
<xsl:when test="$node1">
<xsl:copy-of select="$nodes2[name() = $node1/name()][position() = 1]" />
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$nodes2[1]" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="nodes1After" as="item()*">
<xsl:copy-of select="$nodes1[position() != 1]" />
</xsl:variable>
<xsl:variable name="nodes2After" as="item()*">
<xsl:choose>
<xsl:when test="$node1">
<xsl:copy-of select="$nodes2[not(name() = $node1/name() and position() = 1)]" />
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$nodes2[position() != 1]"></xsl:copy-of>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="not($node1)">
<xsl:copy-of select="$node2" />
</xsl:when>
<xsl:when test="$node1">
<xsl:element name="{$node1/name()}">
<xsl:apply-templates select="$node1/@*" />
<xsl:apply-templates select="$node2/@*" />
<!-- 子要素 -->
<xsl:apply-templates select="self::node()" mode="marge">
<xsl:with-param name="nodes1" select="$node1/node()" />
<xsl:with-param name="nodes2" select="$node2/node()" />
</xsl:apply-templates>
</xsl:element>
<xsl:apply-templates select="self::node()" mode="marge">
<xsl:with-param name="nodes1" select="$nodes1After" />
<xsl:with-param name="nodes2" select="$nodes2After" />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise />
</xsl:choose>
</xsl:template>
</xsl:stylesheet>