我必须创建一个xslt来为2个不同的xsd文件设置交叉,这样一个版本可以匹配另一个版本。我有一个带孩子的元素,其中一些孩子是可选的。在这种情况下。测试3是可选的。
<Test1>
<TestA>data</TestA>
<TestB>data</TestB>
<TestC>data</TestC>
</Test1>
<Test2>
<TestA>data</TestA>
<TestC>data</TestC>
</Test2>
现在我想知道Testb是否存在,如果不存在,我必须将它添加到正确的位置(在Testa和Testc之间)。请注意,Test1已经是其他元素的子元素,我用xsl:for-each“联系”每个元素。
有没有办法做到这一点?谢谢!
要检查元素是否存在,可以将xsl:if
或xsl:when
与test="element_name"
相对应。
执行任务的示例脚本可以如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*[matches(name(),'[a-z]+\d+','i')]">
<xsl:copy>
<xsl:variable name="curr" select="."/>
<xsl:for-each select="('A','B','C')">
<xsl:variable name="childName" select="concat('Test',.)"/>
<xsl:variable name="elem" select="$curr/*[name() = $childName]"/>
<xsl:element name="{$childName}">
<xsl:choose>
<xsl:when test="$elem">
<xsl:value-of select="$elem"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>Surrogate value for </xsl:text>
<xsl:value-of select="$childName"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates/></xsl:copy>
</xsl:template>
</xsl:stylesheet>
主要部分是匹配元素的模板,该名称由字母(至少一个)和数字(再次至少一个)组成。
然后需要curr
变量来保持当前元素,因为for-each
循环改变它,但我们仍然需要对外部当前元素的引用。
For-each
循环安排处理任何子测试...元素,名称以A
,B
或C
结尾。
如果存在所需的子元素,则打印其值,否则脚本将打印相应的代理值。
可能这不是你需要的最终版本,但至少你有一些起点来创建你的最终版本。