This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
XSLTC key() with for-each Problem
- From: Troy Thibodeaux <troythibodeaux at cox dot net>
- To: XSL-List at lists dot mulberrytech dot com
- Date: Fri, 12 Jul 2002 14:57:22 -0500
- Subject: [xsl] XSLTC key() with for-each Problem
- Reply-to: xsl-list at lists dot mulberrytech dot com
Yesterday, I sent a lengthy explanation of an xsltc problem to the list. I
believe it may have bounced because
I used a new email address. If not, my apologies, and please disregard the
earlier post.
The root of my problem is that the XSLTC compiler for Xalan Java 2.4 seems
to behave differently from standard
XSLT processors (including Xalan itself) in the way it handles the
combination of document(), for-each, and
key().
I am attempting to compare specific nodesets from two versions of an XML
file and output a new file that contains only
those nodesets that have been added or changed in the new version.
To do so, I was attempting to employ an idea that Mike Kay presents in his
XSLT Programmer's Reference, involving
the XSLT components listed above (although I may be misapplying this idea):
<xsl:template match="property">
<xsl:variable name="id" select="description/id" />
<xsl:variable name="property" select="." />
<xsl:for-each select="$old_file">
<xsl:if test="not(key('id_group', $id) = $property)">
<xsl:copy-of select="$property" />
</xsl:if>
</xsl:for-each>
</xsl:template>
Each <property> node in the xml contains a unique <id> node. The key()
function matches <property> nodes
using their <id> child.
The idea here is that the <xsl:for-each> will change the current node to
the root of the old file and the key() function will be applied
to that document rather than to the new file, which is the input for the
transformation. This seems to work well when the stylesheet is not
compiled. Properties whose id does not appear in the old file are copied to
the output as are properties that differ from their old version.
When the stylesheet is compiled using XSLTC, however, the key() function in
the <xsl:if> "test" attribute is not applied to $old_file. Instead, the
key() function continues to return nodes from the new document.
I am able to successfully run the transformation if I change the <xsl:if>
to <xsl:if test="not($old_file/properties/property[description/id = $id] =
$property)">, but doing so turns out to be terribly inefficient. This
transformation is to be executed on hundreds of massive documents; hence my
desire both to make the transformation efficient and to compile the stylesheet.
Is there any other way to force the key() function to refer to the nodes in
$old_file? The name of the old file is being passed into the stylesheet as
a parameter, so I don't believe it can be directly referenced in <xsl:key>.
Thanks very much,
Troy Thibodeaux
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list