提问人:deuri 提问时间:3/27/2021 最后编辑:Thomas Hansendeuri 更新时间:3/31/2021 访问量:92
用于创建缺失元素的 XSLT 模板
XSLT templates for creating missing elements confict with each other
问:
我使用 XSLT 转换来添加元素和 XML 数据,以防缺少一个或两个元素。我想使用独立的模板来处理其中的每一个,但似乎只有一个模板生效。configuration
status
源数据:
<data>
<environment>
<id>test</id>
<details>Detail info for environment...</details>
</environment>
<default_conf>abcd1234</default_conf>
<default_status>1</default_status>
</data>
XSLT的:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<!-- identity transformation -->
<xsl:template match="/ | @* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<!-- if configuration not given, create it with the value of default_conf -->
<xsl:template match="data[not(configuration)]">
<xsl:copy>
<xsl:apply-templates/>
<!--xsl:apply-templates select="@*|node()"/-->
<configuration><xsl:value-of select="default_conf"/></configuration>
</xsl:copy>
</xsl:template>
<!-- if status not given, create it with the value of default_status -->
<xsl:template match="data[not(status)]">
<xsl:copy>
<xsl:apply-templates/>
<!--xsl:apply-templates select="@*|node()"/-->
<status><xsl:value-of select="default_status"/></status>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
在结果 XML 中,仅创建元素,而不创建元素。转换模板有什么问题以及如何纠正它?
请注意,我还需要传递 and 元素,因此我不想重命名这些元素。default_conf
default status
期望输出:
<data>
<environment>
<id>test</id>
<details>Detail info for environment...</details>
</environment>
<default_conf>abcd1234</default_conf>
<default_status>1</default_status>
<configuration>abcd1234</configuration>
<status>1</status>
</data>
答:
1赞
michael.hor257k
3/27/2021
#1
在 XSLT 中,
通过查找具有与节点匹配的模式的所有模板规则,并从中选择最佳规则来处理节点;
https://www.w3.org/TR/1999/REC-xslt-19991116/#section-Processing-Model
如果两者都缺少 and,则有两个模板与同一节点匹配,具有相同的优先级。这是一个错误:configuration
status
XSLT 处理器可能会发出错误信号;如果它没有发出错误的信号,则必须通过从剩余的匹配模板规则中选择样式表中最后出现的规则来恢复。
https://www.w3.org/TR/1999/REC-xslt-19991116/#conflict
简单的解决方案是使用带有两条指令的单个模板来添加每个缺失的节点。否则,您需要使用的不是两个,而是三个模板 - 并确保添加的模板优先。xsl:if
评论
0赞
deuri
3/27/2021
感谢 michael.hor257k,它帮助我将解决方案设计为单个模板,每个可选元素都有一个 if 语句。
评论
exsl:node-set
<xsl:if test="not(status)"><status>...</status></xsl:if>