Recker
Recker

Reputation: 1973

Variable not available from one xsl file to other

I am trying to perform XSLT 1.0 transformation using Perl. I am using the solution listed here as my script.

My input xml file looks somewhat like this.

<?xml version="1.0" encoding="UTF-8" ?>
    <bsg>
          <msg>
               <entry key="testingString">This is a test.</entry>
               <!-- <trs> This is me, trs!!! </trs> -->
            </msg>
    </bsg>

trs attribute is optional meaning its not always present in all other entry nodes. Entry can have optional property tslate which can be true or false i.e input xml file can have something like

<entry key="Doctor" tslate="false">Physician.</entry>

To the Perl script, I supply the xslt file which imports two other xslt files (say File A and File B) which has variables and templates defined.

File A reads a node from input xml file as and performs following operation

<xsl:param name="isOTHERFILEavailable"/>    
  <xsl:variable name="tvariables">
    <xsl:choose>
      <xsl:when test="$isOTHERFILEavailable = 'true'">
        <xsl:copy-of select="document($OTHERTHE_File)/bsg/msg"/>
      </xsl:when>
    </xsl:choose>
  </xsl:variable>

isOTHERFILEavailable is a string parameter passed from Perl file that validates whether OTHERFILE exists or not.

This tvariables is then accessed to perform some other operation in File B as below

<xsl:template match="msg">
<xsl:variable name="trsExists">
            <xsl:for-each select="entry">
                <xsl:variable name="current_key" select="@key"/>
                <xsl:variable name="trsMatch" select="$tvariables/msg/entry[@key = $current_key]"/>
                <xsl:choose>
                    <xsl:when test="$trsMatch and normalize-space($trsMatch/text) = normalize-space(.) and (not(@tslate) or @tslate = true())">
                        <xsl:copy>
                            <xsl:copy-of select="$trsMatch/@key|$trsMatch/tvariables/text()|@context"/>                     
                        </xsl:copy>
                    </xsl:when>
                </xsl:choose>
            </xsl:for-each>        
</xsl:variable>
</xsl:template>

My problem is, when I reach this line,

<xsl:variable name="trsMatch" select="$tvariables/msg/entry[@key = $current_key]"/>

Perl errors out as following

Invalid type runtime error: file B.xslt line # element variable Failed to evaluate the expression of variable 'tvariables'

Am I missing something obvious?

P.S => Everything runs fine when run the same transform from Java using XSLT 2.0(Saxon) and even when tvariables is not defined, that is when isOTHERFILEavailable is false.

Upvotes: 0

Views: 79

Answers (1)

Phil Blackburn
Phil Blackburn

Reputation: 1067

$tvariable is a xml fragment.

It seems likely to me that Perl is using a XSL 1.0 Processor. In which case your problem is that $tvariable will need to be converted froma fragment into a node-set before you can use it. XSL 2, handles fragments just as you would expect which is why the code runs in Saxon. Fortunaltely most XSL 1.0 Processors (prehap all?) provide support for fragments with an extension function. You'll need to check your documentation for the details. Your select statement will become something like:

 select="node-set($tvariables)/msg/entry[@key = $current_key]"

Check out http://www.xml.com/pub/a/2003/07/16/nodeset.html for more info about node-set functions.

Upvotes: 1

Related Questions