我正在改进一些我通过使用XSLT进行清理而继承的
XML,但我正在努力解决一个问题.看起来像这样:
<rules>
<if condition="equals" arg1="somevar" arg2="1"/>
<elseif condition="equals" arg1="somevar" arg2="2"/>
<elseif condition="equals" arg1="somevar" arg2="3"/>
<else/>
<if condition="equals" arg1="somevar" arg2="4"/>
<else/>
</rules>
这看起来很难用XSD验证,所以我想把它变成这样的东西 – 想法?
<rules>
<conditionSet>
<if condition="equals" arg1="somevar" arg2="1"/>
<elseif condition="equals" arg1="somevar" arg2="2"/>
<elseif condition="equals" arg1="somevar" arg2="3"/>
<else/>
</conditionSet>
<conditionSet>
<if condition="equals" arg1="somevar" arg2="4"/>
<else/>
</conditionSet>
</rules>
最佳答案 将elseif和else元素按其前面的if元素分组:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="block" match="elseif|else"
use="generate-id(preceding-sibling::if[1])"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="rules">
<xsl:copy>
<xsl:apply-templates select="@*|
node()[not(self::elseif or self::else)]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="if">
<conditionSet>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<xsl:apply-templates select="key('block', generate-id())"/>
</conditionSet>
</xsl:template>
</xsl:stylesheet>
此样式表生成请求的输出.
说明:xsl:key将每个if元素与其后面的相关元素相关联,以便稍后当我们匹配if时,我们可以简单地包装并复制整个集合.