Ada*_*old 3 xml xslt saxon xslt-2.0
假设我有一个这样的A文档:
<document>
<element>
<value>1</value>
<wom>bat</wom>
</element>
<bar>
<baz />
<baz />
<baz />
</bar>
</document>
Run Code Online (Sandbox Code Playgroud)
和这样的B文档:
<document>
<element>
<value>2</value>
</element>
<bar>
</bar>
</document>
Run Code Online (Sandbox Code Playgroud)
结果如下所示:
<document>
<element>
<value>2</value>
<wom>bat</wom>
</element>
<bar>
</bar>
</document>
Run Code Online (Sandbox Code Playgroud)
因此,我想要实现的目标是用文档Belement提供的值覆盖文档A中标记(如 )中的值,但保持同级值不变。然而,如果B中的标签为空(叶),我希望A中的对应标签也被清空。我已经检查过这个问题,但它是合并而不是覆盖。我怎么解决这个问题?
澄清: A和B文档具有相同的结构,但B 的元素较少。我必须清空A中B中为空的每个元素,并且如果元素不为空,我必须覆盖该元素中的每个内部元素(请参阅我的示例)。
一种方法是导航 DocumentA,但将参数集传递给文档 B 中的等效节点。
首先匹配A的文档节点,然后从B的文档节点开始匹配
<xsl:template match="/">
<xsl:apply-templates>
<xsl:with-param name="parentB" select="document('DocB.xml')"/>
</xsl:apply-templates>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
然后,您将拥有一个与 B 中的当前(父)节点作为参数匹配任何元素(A 中)的模板
<xsl:template match="*">
<xsl:param name="parentB"/>
Run Code Online (Sandbox Code Playgroud)
要在 B 中找到等效的“子”节点,首先要找到 A 节点的当前位置(如果有多个同名子节点),然后检查父 B 节点下是否存在这样的子节点
<xsl:variable name="posA">
<xsl:number />
</xsl:variable>
<xsl:variable name="nodeB" select="$parentB/*[local-name() = local-name(current())][number($posA)]"/>
Run Code Online (Sandbox Code Playgroud)
那么,就只是判断是复制A节点还是B节点的情况了。要复制 B 节点,B 节点必须存在,并且没有任何子元素(但它可能有子文本节点,它将被复制
<xsl:when test="$nodeB and not($nodeB/*)">
<xsl:copy-of select="$nodeB/node()"/>
</xsl:when>
Run Code Online (Sandbox Code Playgroud)
否则,继续处理A节点(传入当前B节点作为参数)。
试试这个 XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates>
<xsl:with-param name="parentB" select="document('DocB.xml')"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="*">
<xsl:param name="parentB"/>
<xsl:variable name="posA">
<xsl:number />
</xsl:variable>
<xsl:variable name="nodeB" select="$parentB/*[local-name() = local-name(current())][number($posA)]"/>
<xsl:copy>
<xsl:choose>
<xsl:when test="$nodeB and not($nodeB/*)">
<xsl:copy-of select="$nodeB/node()"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="@*|node()">
<xsl:with-param name="parentB" select="$nodeB"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()[not(self::*)]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)