XSLT 1.0 for-each循环根据BindingMachine存在性生成对应组件元素
XSLT 1.0 动态生成组件元素实现方案
问题根源
你之前逻辑不生效的核心原因是上下文节点切换错误:当判断逻辑写在xsl:for-each select="Product"内部时,当前上下文节点已经变成遍历过程中的单个Product节点,如果BindingMachine是全局节点/Product的上级节点,用相对路径写判断条件会默认查找当前Product子节点下的BindingMachine,自然无法得到正确的判断结果。
标签选择说明
针对你这个双分支互斥的需求:
- 单分支逻辑(满足条件才输出,不满足无输出)优先用
<xsl:if>,写法更简洁 - 双分支逻辑(满足条件输出A,不满足输出B)优先用
<xsl:choose>搭配<xsl:when>、<xsl:otherwise>,语义更清晰,不需要强行用xsl:if实现。
可直接运行的实现代码
优先把元素名的判断逻辑放在for-each外层,只判断一次存入变量,避免循环内重复判断,性能更好:
<!-- 注意:这段代码要放在for-each的外层,保持上下文是根节点/包含BindingMachine的父节点层级 --> <xsl:variable name="componentTag"> <xsl:choose> <!-- 全局查找BindingMachine节点,存在则标签名为BoundComponent --> <xsl:when test="//BindingMachine">BoundComponent</xsl:when> <xsl:otherwise>UnboundComponent</xsl:otherwise> </xsl:choose> </xsl:variable> <!-- 遍历Product节点生成对应元素 --> <xsl:for-each select="Product"> <!-- XSLT 1.0 动态生成元素必须用xsl:element,name属性接收变量值 --> <xsl:element name="{$componentTag}"> <!-- 此处填充每个组件内部的字段映射逻辑即可 --> <xsl:apply-templates/> </xsl:element> </xsl:for-each>
常见踩坑提醒
- 判断节点存在不需要写
count(//BindingMachine) > 0,直接把节点路径作为test属性值即可:选中节点时表达式自动返回true,空节点集返回false,写法更简洁 - 如果
BindingMachine是固定在某个特定路径下(比如根节点下的Config下的BindingMachine),不要用//全局匹配,写绝对路径/Root/Config/BindingMachine匹配效率更高 - XSLT 1.0不支持直接写
<{$componentTag}>这种语法动态生成标签,必须通过xsl:element实现,否则会抛出语法错误。
内容的提问来源于stack exchange,提问作者Bronko
相关产品推荐
相关产品推荐

