Xslt: assigning variables equal to one of two cases

I want to use the @sourcename attribute as follows, as a convenience:

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

Otherwise, $srcgroup should be set to @sourcename , and $srcword should be an empty string.

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

I tried this with the following snippet:

 <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 some other more complicated users of $srcgroup and $srcword --> 

The problem is that 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 assume that the variables have only the specific case area in the <xsl:choose> block. Is there any way around this? I do not want to repeat the second code twice.


ps 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 initial question, for future reference.

+6
source share
2 answers

Just use (optional conditions):

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

Full 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 to this XML document :

 <t> <x sourcename="abc"/> <y sourcename="noDots"/> </t> 

the desired result is created in both cases :

  $srcgroup = "a" $srcword = "bc" $srcgroup = "noDots" $srcword = "" 

The explanation . Unnecessary logic is avoided by the placement of a watchman.


Compare this to the much more detailed 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 detailed conversion is applied to the same XML document (see above), the same correct result is obtained again :

  $srcgroup = "a" $srcword = "bc" $srcgroup = "noDots" $srcword = "" 
+5
source

It looks more like this:

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

Source: https://habr.com/ru/post/907322/


All Articles