[xsl] node-set = node-set involving variable fails

Subject: [xsl] node-set = node-set involving variable fails
From: Roger Glover <glover_roger@xxxxxxxxx>
Date: Thu, 7 Nov 2002 20:24:04 -0800 (PST)
Hello all,

I am currently using Xalan Java 2.4D1 to filter out data from a large (2.5MB)
XML file.  I have a large (90+) number of target values that I wish to use to
extract data from the file.  The idea is to keep the structure of the original
file, but only hold the points in the hierarchy that ultimately contain a
target value.

The input file structure is pretty simple.  The root <dataset> contains
<table>s which contain <column>s (metadata names) and <row>s.  A <row> contains
<value>s and/or <null>s.  If this sounds like a relational database to you, you
win the kewpie doll.

So I am constructing a smaller <dataset> containing only the <table>s that
contain the <row>s that contain the <value>s that match one or more of my
target values.  Furthermore, I am keeping only the <row>s that have matching
<value>s.  I am keeping all the <column>s in any selected <table>s, and all the
<value>s and <null>s in any selected <row>s.

So here is what the main templates look like:

====================================
<xsl:template match="/dataset">
    <dataset>
        <xsl:apply-templates select="table[row[ «value-selector-expr» ]]]"/>
    </dataset>
</xsl:template>

<xsl:template match="table[row[ «value-selector-expr» ]]">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:copy-of select="column"/>
        <xsl:copy-of select="row[ «value-selector-expr» ]"/>
    </xsl:copy>
</xsl:template>
====================================

The trouble I am having is with the «value-selector-expr» expression.  In my
early testing I was successful with an expression of the form:
    value = 'target1' or value = 'target2'

However, I really do not want to use such an expression for over 90 different
target values!!  What I want is to be able to reference the target elements
from within the transform, a la the SQL "IN" syntax.  So I studied Michael
Kay's excellent "XSLT Programmer's Reference" and discovered that:
    o   Expressions of the form "node-set1 = node-set2" are true if any node in
node-set1 has the same sting value as any node in node-set2, so if I could get
the values of a given row to be one node-set, and the entire list of targets to
be the other node-set I would have exaclty what I want
    o   XSLT 1.0 (the version supported by my version of Xalan) does not treat
variables containing sub-elements as full-fledged node-sets, so I cannot just
throw the targets into a variable
    o   There is a work-around using the document() function to make the
transform document introspect itself, thus making variable sub-elements a
potential node-set, which is exactly what I needed.

So here is what my latest attempt looks like:

====================================
<xsl:variable name="targets">
    <target>target1</target>
    <target>target2</target>
         <!-- ....... -->
    <target>target93</target>
</xsl:variable>

<xsl:variable name="targets-1.0"
    select="document('')/*/xsl:variable[@name = 'targets']"
/>

<xsl:template match="/dataset">
    <dataset>
        <xsl:apply-templates
            select="table[row[ value = $targets-1.0/target ]]"
        />
    </dataset>
</xsl:template>

<xsl:template match="table[row[ value = $targets-1.0/target ]]">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:copy-of select="column"/>
        <xsl:copy-of select="row[ value = $targets-1.0/target ]"/>
    </xsl:copy>
</xsl:template>
====================================

Unfortunately this rather convoluted system does not work.  Xalan produces the
following fatal error:
    file:C:/RSS10/database/Test Data/Junits/BaseData2/extract.xslt;
    Line 21; Column 75; XSLT Error (javax.xml.transform.TransformerException):
    java.lang.ClassCastException: org.apache.xpath.objects.XRTreeFrag

Line 21 is the line containing the first (and key!) apply-templates element;
Column 75 is the last character in the expression "value =
$targets-1.0/target".

If anyone can help me debug this snarl, or if anyone can provide a (preferably
simpler) working solution, I would greatly appreciate it.


Thanks in advance!!

-- Roger Glover
   glover_roger@xxxxxxxxx


=====
-- Roger Glover

   "Have you ever noticed, it's 'a penny for your thoughts',
    but you put in your 'two cents worth'?....
    Somebody somewhere is making a penny."
            - Steven Wright

__________________________________________________
Do you Yahoo!?
U2 on LAUNCH - Exclusive greatest hits videos
http://launch.yahoo.com/u2

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread