[xsl] Using a custom variable derived from one XML file to search another and retrieve values of child nodes

Subject: [xsl] Using a custom variable derived from one XML file to search another and retrieve values of child nodes
From: Rob Newman <rlnewman@xxxxxxxx>
Date: Sat, 19 Jul 2008 18:24:29 -0700
Hi there,

My XSLT processor is Saxon v.9. I have an xml file of a list of station names:

stations.xml:

<station_list>
   <stations>
      <station name="MONP">
      <station name="MONP2">
      <station name="PFO">
   </stations>
<station_list>

In another xml file I have a series of values associated with a particular station name (although now the tag is <datalogger>):

dataloggers.xml:

<dataloggerlist>
   <datalogger name="MONP">
      <con>sleeping</con>
      <dlt>280594.003</dlt>
      <rtm>-280553.133</rtm>
   </datalogger>
   <datalogger name="MONP2">
      <con>sleeping</con>
      <dlt>334455.003</dlt>
      <rtm>-483940.133</rtm>
   </datalogger>
   <datalogger name="PFO">
      <con>awake</con>
      <dlt>111111.003</dlt>
      <rtm>-222222.133</rtm>
   </datalogger>
<dataloggerlist>

These are in turn defined in a third xml file (so my xsl processor can convert more than one xml file at a time):

feeder.xml:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<sources>
        <source href="stations.xml" />
        <source href="dataloggers.xml" />
</sources>

I want to combine them together so that the output looks like the code below (Aside: I am aware that the station name could be retrieved from datalogger.xml <datalogger name="XXX">, however I am retrieving a whole suite of other information that is unique to stations.xml and not pertinent to this issue):

output.xml:

<Placemark>
   <name>MONP</name>
   <con>sleeping</con>
   <dlt>280594.003</dlt>
   <rtm>-280553.133</rtm>
</Placemark>
<Placemark>
   <name>MONP2</name>
   <con>sleeping</con>
   <dlt>334455.003</dlt>
   <rtm>-483940.133</rtm>
</Placemark>
<Placemark>
   <name>PFO</name>
   <con>awake</con>
   <dlt>111111.003</dlt>
   <rtm>-222222.133</rtm>
</Placemark>

Where name is derived from stations.xml. To get the con, dlt and rtm values from dataloggers.xml into output.xml I have done the following, although I am not sure this is close to being right:

(1) Open up stations.xml, and using templates I get the value of the station name into a variable called $thisSta
(2) Using the value of $thisSta, I then search for the datalogger tag that has a name attribute that matches $thisSta.
(3) Now I have isolated the station I am interested in from dataloggers.xml I want to grab some values (con, dlt, rtm).


snippet of convert.xsl where I am trying to achieve this:

<xsl:template match="station">
<Placemark>
<xsl:variable name="thisSta"><xsl:value-of select="@name" /></ xsl:variable>
<name><xsl:value-of select="$thisSta" /></name>
<xsl:template match="document( sources/source/@href, .)/ dataloggerlist/datalogger/@name=$thisSta">
<con><xsl:value-of select="con" /></con>
<dlt><xsl:value-of select="dlt" /></dlt>
<rtm><xsl:value-of select="rtm" /></rtm>
</xsl:template>
<Placemark>
</xsl:template>


When I try and process with Saxon, I get the following output:

Error at xsl:template on line 102 of file:convert.xsl:
XTSE0340: XSLT Pattern syntax error at char 0 on line 102 in {document( sources}:
The only functions allowed in a pattern are id() and key()


The error is the second template match statement. I think I am pretty close to getting this working, but I have run out of ideas. Can you do what I am trying to achieve, or is my XPath expression syntax just poorly written?

Thanks in advance,
- Rob

Current Thread