我需要一个XSLT转换,它将整个输入文档复制到输出文档,如果输入文档不包含该元素,则插入一个具有默认值的特定元素。
具体来说,我想转换这种一般形式的输入XML
/Begin/tag1
自身,但如果输入没有<Begin>
<tag2>c</tag2>
</Begin>
,那么我想提供一个。也就是说,我想转换
<Begin>
<tag1>x</tag1>
<tag2>c</tag2>
</Begin>
到
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这是我目前的XSLT:
<tag1>
它复制整个输入文档,但不提供默认的<xsl:choose>
元素。我无法在该样式表中的模板中使用<tag1>
,因为它会将choose
插入到没有一个的永久元素中,并且我不能在{/ 1}} 之后放置1> em>模板,因为它无效。如何为<tag1>
元素提供默认的<Begin>
元素 ?
答案 0 :(得分:1)
如果模板没有Begin
,您可以添加与tag1
匹配的模板并插入tag1
。请注意,这适用于您非常简单的示例,但如果您有一个更复杂的情况,需要插入大量元素或多个元素,那么解决方案可能会变得更加复杂。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Begin[not(tag1)]">
<xsl:copy>
<xsl:apply-templates select="@*" />
<tag1>x</tag1>
<xsl:apply-templates select="node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
您是正确的,不能将<xsl:choose>
元素放在模板之外。 XSL通过转换输入文档的节点来运行;您只能根据特定节点的转换方式来表达转换的细节 - 即通过模板。
此外,通过提供替代模板或select
表达式来表达替代方案通常比在模板中使用<xsl:choose>
<xsl:if>
等逻辑元素更自然。
在这种情况下,您有两种选择:
/Begin
元素有一个tag1
孩子/Begin
元素没有tag1
孩子在第一种情况下,你不需要做任何特别的事情 - 你已经写过的身份变换会做正确的事情。那么,您所需要的只是处理后一种选择的合适模板。只要它具有比身份变换更高的优先级,它将用于Begin
元素而不是身份变换,无论它适用于何处。
例如,
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Begin[count(tag1) = 0]">
<xsl:copy>
<tag1>x</tag1>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
请注意添加的模板,该模板仅适用于没有Begin
子元素的<tag1>
元素。它复制整个元素及其子节点,但也插入<tag1>
。