xslt:分配等于两种情况之一的变量

发布于 2025-01-01 10:00:22 字数 1789 浏览 1 评论 0原文

为了方便起见,我想按以下方式使用属性 @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 -->

问题是我收到错误(这是在 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)

如果我理解正确,我猜测变量仅具有 < 中特定情况的范围;xsl:choose> 块。有什么办法可以解决这个问题吗?我不想重复我的其他代码两次。


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

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

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

I want to use the attribute @sourcename in the following way, as a convenience:

If @sourcename has a dot in it, the part before the first dot should be assigned to $srcgroup and the part after the first dot should be assigned to $srcword.

Otherwise $srcgroup should be set equal to @sourcename and $srcword should be the empty string.

In both cases I want to do the same things using $srcgroup and $srcword.

I tried this with the following fragment:

<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 -->

The problem is I get an error (this is using JAXP in Java):

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)

If I understand this right, I'm guessing the variables only have the scope of the particular case in the <xsl:choose> block. Is there any way to get around this? I don't want to have to repeat my other code twice.


p.s. I found a workaround:

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

but I still want to know how to solve my original question, for future reference.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

枕头说它不想醒 2025-01-08 10:00:22

只需使用(无需条件):

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

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

完整示例

<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>

应用于此 XML 文档时

<t>
  <x sourcename="a.b.c"/>
  <y sourcename="noDots"/>
</t>

两种情况都会产生所需的结果

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

  $srcgroup = "noDots"
  $srcword = ""

解释:通过放置哨兵可以避免不必要的逻辑。


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

<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>

当将这种更详细的转换应用于同一个 XML 文档(如上)时,会再次生成相同的正确结果

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

  $srcgroup = "noDots"
  $srcword = ""

Just use (no conditionals necessary):

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

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

Complete example:

<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>

when applied on this XML document:

<t>
  <x sourcename="a.b.c"/>
  <y sourcename="noDots"/>
</t>

the wanted result is produced in both cases:

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

  $srcgroup = "noDots"
  $srcword = ""

Explanation: Unnecessary logic avoided by placing a sentinel.


Compare this to the much more verbose conditional syntax:

<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>

When this more verbose transformation is applied on the same XML document (above), again the same correct result is produced:

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

  $srcgroup = "noDots"
  $srcword = ""
挖个坑埋了你 2025-01-08 10:00:22

它更像是这样的:

<xsl:variable name="srcgroup">
 <xsl:choose...>
  ...
 </xsl:choose>
</xsl:variable>

It's more like this:

<xsl:variable name="srcgroup">
 <xsl:choose...>
  ...
 </xsl:choose>
</xsl:variable>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文