Re: [xsl] for-each tokenize() and context problem

Subject: Re: [xsl] for-each tokenize() and context problem
From: Mukul Gandhi <gandhi.mukul@xxxxxxxxx>
Date: Fri, 20 Nov 2009 08:58:22 +0530
Sorry I haven't read your use case in detail. But from XSLT language
perspective, it's probably better to declare the variable you used, as
following:

<xsl:variable name="l_GetPartNumber" as="xs:string*">
  ...
</xsl:variable>

XSLT 2.0 allows us to specify the type of a variable like, as
xs:string* above which brings the advantages to strong typing, as we
have been discussing in other threads lately.

I think, if we declare a variable as following:

<xsl:variable name="l_GetPartNumber">
  ...
</xsl:variable>

The contents of the variable are the output of some sequence
instruction(s), probably, let's say which (the sequence instructions)
produce data of some XDM type.

Depending on where the variable, l_GetPartNumber is used after
declaration, the variable will be coerced to the type required by the
evaluation in a given context (I don't mean though the XSLT language
term, context :)) which is probably expensive for XSLT processor to
do, and also probably not a good program design.

So in a nutshell, I would recommend to declare the types of variables
(or whatever XSLT 2 instructions allow us to specify types, like also
for e.g, <xsl:param name="x" as="xs:string" />) whereever we can know
before compilation of the stylesheets, what the types of data should
be.

On Thu, Nov 19, 2009 at 10:57 PM, Mario Madunic
<Mario_Madunic@xxxxxxxxxxxx> wrote:
> I have the following variable,
>
> <xsl:variable name="l_GetPartNumber">
> B <xsl:for-each select="tokenize(normalize-space($l_Components), ' ')">
> B  B <xsl:variable name="l_Num" select="." />
> B  B <xsl:for-each select="ancestor::*[self::page]/row[entry[1] =
$l_Num]/entry[3]">
> B  B  B <xsl:value-of select="concat(' ', .)" />
> B  B </xsl:for-each>
> B </xsl:for-each>
> </xsl:variable>
>
> <xsl:attribute name="partsList" select="normalize-space(concat('- ', $
l_GetPartNumber, ' -'))" />
>
> It is all within a <template match="entry[contains(., ' (Incl. ')]">...</>
>
> $l_Components is a variable that contains a list of numbers stripped from
the last <entry /> and all ranges (7...11) expanded (7 8 9 10 11) and all
commas and ampersands removed. I end up with a tokenized list, such as this "3
5 7 8 9 10 11 13". A sample of the XML is below
>
> <pages>
> B <page>
> B  B <row>
> B  B  B <entry>1</entry><!-- a quirk, can appear multiple times with the
same parent, same value, and have different part numbers (options to the first
one mentioned) -->
> B  B  B <entry>quantity</entry>
> B  B  B <entry>part number</entry>
> B  B  B <entry>part description</entry>
> B  B <row>
> B  B <row>
> B  B  B <entry>2</entry>
> B  B  B <entry>quantity</entry>
> B  B  B <entry>part number</entry>
> B  B  B <entry>part description, (Incl. 3, 5, 7...11, & 13)</entry>
> B  B <row>
> B  B ...
> B </page>
> </pages>
>
> The following step is replace the row number with the part number. The XPath
"ancestor::*[self::page]/row[entry[1] = $l_Num]/entry[3]" works outside of the
variable it is in. But once I do the above (var name = l_GetPartNumber), I
receive the following error msg.
>
> Fatal Error! Axis step ancestor::element() cannot be used here: the context
item is an atomic value
>
> Am I going about this the wrong way? Any insight would be appreciated.
>
> Marijan (Mario) Madunic
> Publishing Specialist
> New Flyer Industries
> (204) 934 8815
> mario_madunic@xxxxxxxxxxxx



--
Regards,
Mukul Gandhi

Current Thread