This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

XSLTC key() with for-each Problem


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]