我在XSLT文件中使用以下XSLT函数来生成XHTML输出:
<xsl:function name="local:if-not-empty">
<xsl:param name="prefix"/>
<xsl:param name="str"/>
<xsl:param name="suffix"/>
<xsl:if test="$str != ''"><xsl:value-of select="concat($prefix, $str, $suffix)"/></xsl:if>
</xsl:function>
它只检查字符串str
是否为空,如果是,则返回字符串,与前缀和后缀连接。
只要我只传递简单字符串,该函数就可以正常工作。但是当我尝试将HTML元素作为前缀或后缀传递时,例如:
<xsl:value-of select="local:if-not-empty('', /some/xpath/expression, '<br/>')"/>
我收到以下错误消息:
SXXP0003: Error reported by XML parser: The value of attribute "select"
associated with an element type "null" must not contain the '<' character.
我接下来尝试的是定义一个变量:
<xsl:variable name="br"><br/></xsl:variable>
并将其传递给函数:
<xsl:value-of select="local:if-not-empty('', /some/xpath/expression, $br)"/>
但是在这里,当然,我得到一个空字符串,因为提取了元素的值,而不是元素本身被复制。
我最后的绝望尝试是在变量中定义一个文本元素:
<xsl:variable name="br">
<xsl:text disable-output-escaping="yes"><br/></xsl:text>
</xsl:variable>
并将其传递给函数,但这也是不允许的。
XTSE0010: xsl:text must not contain child elements
我可能不理解XSLT的复杂内部工作原理,但在我看来,通过泛型函数在XSLT转换中添加<br/>
元素似乎是合法的......
无论如何......如果有人能给我一个替代解决方案,我会很感激。我也想明白为什么这不起作用......
PS:我正在使用Saxon-HE 9.4.0.1J,Java版本1.6.0_24
答案 0 :(得分:2)
使用:concat
代替<xsl:copy-of>
,并将项作为参数传递而不是字符串:
<xsl:copy-of select="$pPrefix"/>
<xsl:copy-of select="$pStr"/>
<xsl:copy-of select="$pSuffix"/>
以下是完整示例:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:local="my:local" exclude-result-prefixes="local">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vBr"><br/></xsl:variable>
<xsl:template match="/">
<xsl:sequence select="local:if-not-empty('a', 'b', $vBr/*)"/>
</xsl:template>
<xsl:function name="local:if-not-empty">
<xsl:param name="pPrefix"/>
<xsl:param name="pStr"/>
<xsl:param name="pSuffix"/>
<xsl:if test="$pStr != ''">
<xsl:copy-of select="$pPrefix"/>
<xsl:copy-of select="$pStr"/>
<xsl:copy-of select="$pSuffix"/>
</xsl:if>
</xsl:function>
</xsl:stylesheet>
当对任何XML文档(未使用)应用此转换时,会生成所需的正确结果:
a b<br/>
答案 1 :(得分:1)
试试这个:
<xsl:value-of select="local:if-not-empty('', /some/xpath/expression, '<br/>')" disable-output-escaping="yes"/>
答案 2 :(得分:0)
问题是<br/>
不是字符串 - 它是一个XML元素,因此无法使用字符串函数进行操作。你需要一个像这样的独立功能:
<xsl:function name="local:br-if-not-empty">
<xsl:param name="prefix"/>
<xsl:param name="str"/>
<xsl:if test="$str != ''">
<xsl:value-of select="concat($prefix, $str)"/>
<br/>
</xsl:if>
</xsl:function>
或像这样的“技巧”,你将<br/>
作为一个单独的案例处理:
<xsl:function name="local:if-not-empty">
<xsl:param name="prefix"/>
<xsl:param name="str"/>
<xsl:param name="suffix"/>
<xsl:if test="$str != ''">
<xsl:value-of select="concat($prefix, $str)"/>
<xsl:choose>
<xsl:when test="$suffix = '<br/>'>
<br/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$suffix"/>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:function>