xsl-list
[Top] [All Lists]

[xsl] document tree fragments

2008-10-11 04:32:37
Hello all,

XSLT 1.0 (i.e. Firefox 3.0, etc.)
XSLT 2.0 solutions not suitable.

I have a working xsl stylesheet that transforms an xml file with the
structure:

< wines >
        < wine >...< /wine >+
< /wines >

I want, now, to rewrite my xsl stylesheet to work with a collection of xml files, each of which contain an individual < wine > element--i.e. in place of the single xml < wines > file.

I have succeeded, but with two problems. Firstly, I am unable to separately specify the directory path of the files. Here is my "base" xml file's content:

<docs path="jb">
        <doc filename="jb/wine1.xml" />
        <doc filename="jb/wine2.xml" />
        <doc filename="jb/wine3.xml" />
        ...
</docs>

Note that I have provided the directory path within the @filename attribute, but I would prefer to retrieve it from the @path attribute.

Here is the part of my xsl stylesheet that retrieves the contents of my collection of xml files:

<xsl:template match="/docs">
        <xsl:variable name="thePath" select="@path" />
        <xsl:variable name="theWines" select="document(doc/@filename)/wine" />
...

Is there a way to use my $thePath variable, instead of including the directory path inside the @filename attribute? I tried to concatenate, but without success. I want to deal with all my xml files together, rather than using a for-each loop, because of several aggregate processes that I want to apply.


Secondly, I'm not sure I fully understand what my $theWines variable now contains. I believe it is a collection of tree fragments--i.e. there's no single top-most node, is that right? Or is there an implicit / (document) node?

The reason I ask is because I have some templates that rely on processing the preceding axis, and whereas my templates work fine for my < wines > xml file, they do not produce the anticipated results when using my $theWines variable.

This template works with the < wines > xml file, and is called by another template that has already matched the "wines" node:

<xsl:template name="winesByCountry">
        <table border="1">
<xsl:for-each select="wine/countries/country[not(name=../../preceding-sibling::wine/countries/country/name)]">
        <xsl:sort select="name" order="ascending" />
        <xsl:variable name="countryName" select="name" />
        <tr><th><xsl:value-of select="$countryName" /></th><td>
<xsl:value-of select="count(/wines/wine/countries/country[name = $countryName])" /></td></tr>
        </xsl:for-each>
        </table>
</xsl:template>


The following template does not work. It outputs each country multiple times--e.g. 2 wines from Italy are output twice as:

Italy 2
Italy 2

rather than the second time correctly seeing that that country is already present in a preceding node:

<xsl:template name="winesByCountry">
        <xsl:param name="theWines" />
        <table border="1">
<xsl:for-each select="$theWines/countries/country[not(name=preceding::country/name)]">
        <xsl:sort select="name" order="ascending" />
        <xsl:variable name="countryName" select="name" />
        <tr><th><xsl:value-of select="$countryName" /></th><td>
<xsl:value-of select="count($theWines/countries/country[name=$countryName])" /></td></tr>
        </xsl:for-each>
        </table>
</xsl:template>


Do I need to wrap the sequence of tree fragments in my $theWines variable inside a node? I tried using the following:

<xsl:variable name="theWines">
        <wines>
        <xsl:value-of select="document(doc/@filename)/wine" />
        </wines>
</xsl:variable>


but Firefox says: Error during XSLT transformation: An XPath expression was expected to return a NodeSet.

Sorry for the length. Any suggestions?

Cheers!

Joe


--~------------------------------------------------------------------
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>
--~--

<Prev in Thread] Current Thread [Next in Thread>