xsl-list
[Top] [All Lists]

Re: [xsl] Passing tree fragment as a tunneled param to be accessed by key

2006-05-14 22:34:42
My apologies for missing the tunnel attribute on the param element in
my template. I overlooked it while creating my example. However, I'm
glad I asked; your suggestions will be heeded in the future.

The source of my original problem rested with the difference between:

$objects/key('objects',@ref)/@out-id

and

key('objects',@ref,$objects)/@out-id

Before today, I thought these were 'equivalent'. It appears if one
wants to 'continue' walking the xpath, the latter is needed. If the
former is used, things go awry.

Is there a good description for the subtle differences between these
two statements?

Thanks yet again,
Tim

On 5/14/06, Michael Kay <mike(_at_)saxonica(_dot_)com> wrote:
The variable

  <xsl:param name="objects"/>

is unrelated to the variable

 <xsl:with-param name="objects" select="$objects" tunnel="yes"/>

because one is a tunnel parameter and the other isn't. So the non-tunnel
parameter gets it's default value, which is "".

To correct this, specify

<xsl:param name="objects" tunnel="yes"/>

To prevent it happening again (or to get better diagnostics next time you
make the mistake), some good practices are:

(a) On a parameter, specify required="yes" if you expect a value to be
supplied

(b) Declare the expected types of your parameters. Thus:

<xsl:param name="objects" required="yes" tunnel="yes" as="document-node()"/>

Michael Kay
http://www.saxonica.com/

> -----Original Message-----
> From: Tim Lebo [mailto:timleboxslt(_at_)gmail(_dot_)com]
> Sent: 14 May 2006 23:33
> To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
> Subject: [xsl] Passing tree fragment as a tunneled param to
> be accessed by key
>
> All,
>
> The input and output formats that I am working with both use IDs.
> Unfortunately, the mapping between the IDs is rather complex.
> Fortunately, I can dymanically determine the mapping. This is
> done by creating elements within the transform (and in its
> own namespace) that pair the ids. All of these pairings sit
> in a variable in the / template.
>
> My problem: While I'm processing the input structure with
> apply-templates, when the input refers to an id, I need to
> dip into my pairings variable to look up the appropriate
> output id. I use a key for this and use the pairings variable
> to define the tree fragment scope for the key. It appears
> that when I pass the pairing variable into the
> apply-templates, it becomes a string and is not recognized as
> a tree fragment.
>
> Hopefully any ambiguity of my description will be absolved
> with the following domain-independent code. The Input,
> current xsl, and desired output follow.The xsl includes
> comments describing current problem in code.
>
> Kindest thanks and highest regards,
> Tim
>
> current xsl throws two errors:
>
> Error on line 34 of file:/Users/tml/Desktop/question/attempt.xsl:
>   XPTY0019: Required item type of first operand of '/' is
> node(); supplied value has item
>   type xs:string
> Transformation failed: Run-time errors were reported
>
> Error on line 37 of file:/Users/tml/Desktop/question/attempt.xsl:
>   XPTY0019: Required item type of first operand of '/' is
> node(); supplied value has item
>   type xs:string
> Transformation failed: Run-time errors were reported
>
>
> ======== input ==========
> <in-objects>
>   <in-object ref="AAA"/>
>   <in-object ref="BBB"/>
>   <in-object ref="CCC"/>
> </in-objects>
>
>
> ======== desired output =========
> 3
> <out-object>
>    <refers-to>input @ref: AAA count($objects/*): 3 get
> @out-id: 111</refers-to> </out-object>
>
>
> ========= current xsl ==========
> <xsl:transform version="2.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>   xmlns:xfm="intermediate nodes created during transform not
> in input and not for final output"
>   exclude-result-prefixes="xfm">
>
> <xsl:output method="xml" indent="yes"/>
> <xsl:key name="objects" match="xfm:object" use="@in-id"/>
>
> <xsl:template match="/">
>   <xsl:variable name="objects">
>     <!-- This would be generated with an apply-templates, but
> is hard coded for example -->
>     <xfm:object in-id="AAA" out-id="111">text a 1</xfm:object>
>     <xfm:object in-id="BBB" out-id="222">text b 2</xfm:object>
>     <xfm:object in-id="CCC" out-id="333">text c 3</xfm:object>
>   </xsl:variable>
>   <xsl:value-of select="count($objects/*)"/>
>   <xsl:apply-templates select="in-objects">
>     <xsl:with-param name="objects" select="$objects" tunnel="yes"/>
>   </xsl:apply-templates>
> </xsl:template>
>
> <xsl:template match="in-objects">
>   <xsl:apply-templates select="in-object[1]"/> </xsl:template>
>
> <xsl:template match="in-object">
>   <xsl:param name="objects"/>
>   <out-object>
>     <refers-to>
>
>       <xsl:value-of select="concat('input @ref: ',@ref,' ')"/>
>
>       <!-- LINE 34: I expect $objects to be a tree fragment
> of 3 xfm:object here, but it is a string. -->
>       <xsl:value-of select="concat('count($objects/*):
> ',count($objects/*),' ')"/>
>
>       <!-- LINE 37: After $objects is a tree fragment here,
> this does not select '111' -->
>       <xsl:value-of select="concat('get @out-id:
> ',$objects/key('objects',@ref)/@out-id)"/>
>
>     </refers-to>
>   </out-object>
> </xsl:template>
>
> <xsl:variable name="NL">
> <xsl:text>
> </xsl:text>
> </xsl:variable>
>
> </xsl:transform>
>
> --~------------------------------------------------------------------
> XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
> or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
> --~--
>


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--