如何将HTML元素作为参数传递给XSLT函数?

如何将HTML元素作为参数传递给XSLT函数?,xslt,xslt-2.0,Xslt,Xslt 2.0,我在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(

我在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>
我收到以下错误消息:

SXXP0003: Error reported by XML parser: The value of attribute "select"
associated with an element type "null" must not contain the '<' character.
我可能不理解XSLT复杂的内部工作原理,但在我看来,通过泛型函数在XSLT转换中添加

元素似乎是合法的

无论如何。。。如果有人能给我一个替代方案,我将不胜感激。我也想了解为什么这不起作用

PS:我正在使用Saxon HE 9.4.0.1J,Java版本1.6.0_24

<xsl:value-of select="local:if-not-empty('', /some/xpath/expression, '&lt;br/&gt;')" disable-output-escaping="yes"/>

试试这个:

<xsl:value-of select="local:if-not-empty('', /some/xpath/expression, '&lt;br/&gt;')" disable-output-escaping="yes"/>

问题在于

不是字符串-它是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> 


或者像这样的“把戏”,将

作为单独的案例处理:

<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 = '&lt;br/&gt;'>
             <br/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$suffix"/>
          </xsl:otherwise>
       </xsl:choose>
    </xsl:if> 
</xsl:function> 


问题在于

不是字符串-它是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> 


或者像这样的“把戏”,将

作为单独的案例处理:

<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 = '&lt;br/&gt;'>
             <br/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$suffix"/>
          </xsl:otherwise>
       </xsl:choose>
    </xsl:if> 
</xsl:function> 


使用:
而不是
concat
,并作为参数项而不是字符串传递:

   <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>
a b<br/>


将此转换应用于任何XML文档(未使用)时,将生成所需的正确结果

<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>
a b<br/>
ab

使用:
并将项目作为参数传递,而不是字符串:

   <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>
a b<br/>


将此转换应用于任何XML文档(未使用)时,将生成所需的正确结果

<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>
a b<br/>
ab

谢谢,这很有效。。。虽然有点难看和罗嗦。。。也许我会为

使用一个专用函数,但这个解决方案不是将

添加为字符串而不是元素吗?也就是说,您在输出中得到了
br/
?@PeterNeuhaus:它之所以有效,是因为
禁用输出转义
指令-但是如果您的字符串包含
谢谢,那就行了。。。虽然有点难看和罗嗦。。。也许我会为

使用一个专用函数,但这个解决方案不是将

添加为字符串而不是元素吗?也就是说,您在输出中得到了
br/
?@PeterNeuhaus:它之所以有效,是因为
禁用输出转义
指令-但是如果您的字符串包含
谢谢,这就可以了。我不熟悉
xsl:sequence
。当使用XPath表达式作为参数调用时(如在我的初始示例中),可能需要选择所选元素的文本节点:
@PeterNeuhaus:不能将元素的文本表示形式作为参数传递。此解决方案创建一个临时树,其子节点作为函数的第三个参数传递。您需要了解,

只是一个字符串,而不是一个节点,但您不想生成字符串,而是想生成一个节点。谢谢,这很好。我不熟悉
xsl:sequence
。当使用XPath表达式作为参数调用时(如在我的初始示例中),可能需要选择所选元素的文本节点:
@PeterNeuhaus:不能将元素的文本表示形式作为参数传递。此解决方案创建一个临时树,其子节点作为函数的第三个参数传递。您需要了解,

只是一个字符串——不是节点——但您不想生成字符串——您想生成一个节点。单独的函数或案例可以工作,但我必须为每个可能的参数添加一个新函数或when块。这将导致大量重复代码,这将是维护的噩梦。@PeterNeuhaus:Dimitre以上的解决方案是分离函数或案例工作的方法,但我必须为每个可能的参数添加一个新函数或when块。这将导致大量重复的代码,这将是一场维护的噩梦。@PeterNeuhaus:Dimitre以上的解决方案是一条出路,感谢所有回答我问题的人。最适合我的解决方案是下面Dimitre Novatchev的解决方案。感谢所有回答我问题的人。最适合我的解决方案是下面Dimitre Novatchev的解决方案。