xslt:赋值变量等于两种情况之一

Jas*_*n S 6 xslt conditional

我想以@sourcename下列方式使用该属性,为方便起见:

如果其中@sourcename有一个点,则应指定第一个点之前的部分,$srcgroup并指定第一个点之后的部分$srcword.

否则$srcgroup应设置为等于@sourcename$srcword应为空字符串.

在这两种情况下,我都希望使用$srcgroup和做同样的事情$srcword.

我尝试使用以下片段:

<xsl:choose>
   <xsl:when test="contains(@sourcename, '.')">     
     <xsl:variable name="srcgroup" select="substring-before(@sourcename, '.')"/> 
     <xsl:variable name="srcword" select="substring-after(@sourcename, '.')" />
   </xsl:when> 
   <xsl:otherwise>
     <xsl:variable name="srcgroup" select="@sourcename" />
     <xsl:variable name="srcword" />                     
   </xsl:otherwise>
</xsl:choose>

<foo group="{$srcgroup}" word="{$srcword}" />
<!-- there's some other more complicated users of $srcgroup and $srcword -->
Run Code Online (Sandbox Code Playgroud)

问题是我得到一个错误(这是在Java中使用JAXP):

ERROR:  [my xsl file]: line 35: Variable or parameter 'srcgroup' is undefined.'
FATAL ERROR:  'Could not compile stylesheet'
Exception in thread "main" javax.xml.transform.TransformerConfigurationException: Could not compile stylesheet
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:825)
Run Code Online (Sandbox Code Playgroud)

如果我理解这一点,我猜测变量只有<xsl:choose>块中特定情况的范围.有没有办法解决这个问题?我不想两次重复我的其他代码.


ps我找到了一个解决方法:

<xsl:variable name="srcgroup" select="substring-before(concat(@sourcename, '.'), '.')" /> 
<xsl:variable name="srcword" select="substring-after(@sourcename, '.')" />
Run Code Online (Sandbox Code Playgroud)

但我仍然想知道如何解决我原来的问题,以备将来参考.

Mic*_*ker 5

它更像是这样的:

<xsl:variable name="srcgroup">
 <xsl:choose...>
  ...
 </xsl:choose>
</xsl:variable>
Run Code Online (Sandbox Code Playgroud)


Dim*_*hev 5

只需使用(无需条件):

  <xsl:variable name="srcgroup" select=
  "substring-before(concat(@sourcename, '.'), '.')"/>

  <xsl:variable name="srcword" select=
  "substring-after(@sourcename, '.')"/>
Run Code Online (Sandbox Code Playgroud)

完整的例子:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="x|y">
  <xsl:variable name="srcgroup" select=
  "substring-before(concat(@sourcename, '.'), '.')"/>

  <xsl:variable name="srcword" select=
  "substring-after(@sourcename, '.')"/>

  $srcgroup = "<xsl:value-of select="$srcgroup"/>"
  $srcword = "<xsl:value-of select="$srcword"/>"
 </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

应用于此XML文档时:

<t>
  <x sourcename="a.b.c"/>
  <y sourcename="noDots"/>
</t>
Run Code Online (Sandbox Code Playgroud)

在两种情况下都会产生想要的结果:

  $srcgroup = "a"
  $srcword = "b.c"

  $srcgroup = "noDots"
  $srcword = ""
Run Code Online (Sandbox Code Playgroud)

说明:放置一个标记可以避免不必要的逻辑.


将此与更详细的条件语法进行比较:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="x|y">
  <xsl:variable name="srcgroup">
   <xsl:choose>
     <xsl:when test="contains(@sourcename, '.')">
      <xsl:value-of select="substring-before(@sourcename, '.')"/>
     </xsl:when>
     <xsl:otherwise>
      <xsl:value-of select="@sourcename"/>
     </xsl:otherwise>
   </xsl:choose>
  </xsl:variable>

  <xsl:variable name="srcword">
   <xsl:choose>
     <xsl:when test="contains(@sourcename, '.')">
      <xsl:value-of select="substring-after(@sourcename, '.')"/>
     </xsl:when>
     <xsl:otherwise/>
   </xsl:choose>
  </xsl:variable>

  $srcgroup = "<xsl:value-of select="$srcgroup"/>"
  $srcword = "<xsl:value-of select="$srcword"/>"
 </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

当对同一XML文档(上面)应用这种更详细的转换时,再次产生相同的正确结果:

  $srcgroup = "a"
  $srcword = "b.c"

  $srcgroup = "noDots"
  $srcword = ""
Run Code Online (Sandbox Code Playgroud)