XSLT 3.0条件动态创建元素报错,求可行实现方案
解决XSLT中动态创建元素时标签不匹配的问题
你遇到的错误本质是XML语法的严格嵌套要求——XSLT本身是XML的一种应用,所以所有元素必须正确嵌套,不能把<xsl:element>的开始标签和结束标签拆分到两个独立的<xsl:if>块里,哪怕你的逻辑上想让它们成对,XML解析器也会直接判定语法错误。
下面给你几个可行的解决方案:
方案1:将整个元素包裹在单个条件块中
如果只有当$courseType = 'B'时才需要输出newElement及其内部内容,直接把整个<xsl:element>(包括它包裹的所有节点)放在一个<xsl:if>里即可:
<xsl:variable name="courseType" select="Record[1]/course-type"/> <xsl:if test="$courseType = 'B'"> <xsl:element name="newElement"> <!-- 这里放你原来写在两个if之间的"其他节点" --> <some-node>内容</some-node> <another-node>更多内容</another-node> </xsl:element> </xsl:if>
这样既符合XML的嵌套规则,又能实现“仅当courseType为B时创建newElement并包裹内部内容”的需求。
方案2:用xsl:choose避免重复代码(如果内容需要无条件输出)
如果那些“其他节点”不管courseType的值都要输出,只是当courseType = 'B'时需要把它们包裹在newElement里,直接写两次内容会导致代码重复。这时候可以把公共内容抽成模板,再用<xsl:choose>分支处理:
第一步:定义公共内容模板
<xsl:template name="common-content"> <!-- 这里放你原来的"其他节点" --> <some-node>内容</some-node> <another-node>更多内容</another-node> </xsl:template>
第二步:根据条件选择输出方式
<xsl:variable name="courseType" select="Record[1]/course-type"/> <xsl:choose> <xsl:when test="$courseType = 'B'"> <xsl:element name="newElement"> <xsl:call-template name="common-content"/> </xsl:element> </xsl:when> <xsl:otherwise> <xsl:call-template name="common-content"/> </xsl:otherwise> </xsl:choose>
这种方式既保证了XML语法正确,又避免了重复编写相同的内容。
为什么原写法不行?
再强调一下:XML解析器在处理XSLT文件时,会先做语法校验,而不是先执行你的逻辑。原写法中,第一个<xsl:if>里只有<xsl:element>的开始标签,没有结束标签,解析器会直接判定这是不完整的元素,所以抛出“必须由匹配的结束标记终止”的错误——它不会等到执行时再去匹配另一个<xsl:if>里的结束标签。
内容的提问来源于stack exchange,提问作者pshemek
相关产品推荐
相关产品推荐

