user2462093
user2462093

Reputation: 71

XSLT: Variables and Parameters not passing

I have an xslt file that just will not pass parameters and I can't figure out why.

I have done this before but not sure what I am missing.

I tried setting a global variable, but that doesn't seem to get set.

I try passing a local variable which is set, but it doesn't pass. I wanted to go directly to my "SALES/SUBJECT" element, but it would lose the variable and I remember this problem before having to do with Built-in Rules.xsl file, so I go the the ELEMENT "SALES" first to try to get around it but it still seemed to go there. But I found that the parameter was blank before then anyway.

The XML file is:

<?xml version="1.0"?>
<REPORT VERSION="1.30" MAJORFORM="TomsForm">
  <SALES>
    <SUBJECT LATITUDE="32.2222" LONGITUDE="-118.222222">
      <BUSINESS>Joes Bar and Grill</BUSINESS>
    </SUBJECT>
  </SALES>
</REPORT>

The first XSLT file which just tries to set up a global variable, doesn't work. If I stop at the line where the "majorForm" is set and look at the watch window, @MAJORFORM shows as "TomsForm", which it should. But when I step to the next line, it is blank. So down further where I use it, it is also blank because of that.

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:output method="xml" indent="yes"/>
  <xsl:variable name="majorForm" select="@MAJORFORM"/>

  <xsl:template match="/*">
    <xsl:copy>

      <xsl:apply-templates select="SALES/SUBJECT"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="SALES/SUBJECT">
    <xsl:for-each select ="@*">
      <xsl:if test="name() = 'LATITUDE'">
        <form>
          <formName>
            <xsl:value-of select="$majorForm"/>
          </formName>
        </form>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

In the other file I set it as a local file and it does set $majorForm to "TomsForm", but when I pass it at the apply-templates, it never passes anything. But the code sees it as a valid parameter, just that there is nothing in it.

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/*">
    <xsl:copy>

      <xsl:variable name="majorForm" select="@MAJORFORM"/>

      <xsl:apply-templates select="SALES">
        <xsl:with-param name="mainform" select="$majorForm"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>


  <xsl:template match="SALES">
    <xsl:param name="mainForm"/>
    <xsl:for-each select ="@*">
    </xsl:for-each>
    <xsl:apply-templates>
      <xsl:with-param name="mainForm" select="$mainForm"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="SALES/SUBJECT">
    <xsl:param name="mainForm"/>
    <xsl:for-each select ="@*">
      <xsl:if test="name() = 'LATITUDE'">
        <form>
          <formName>
            <xsl:value-of select="$mainForm"/>
          </formName>
        </form>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

I have done this before and it would work fine.

I would like to find out why neither of these ways works.

Upvotes: 2

Views: 2090

Answers (1)

Mads Hansen
Mads Hansen

Reputation: 66781

In your first stylesheet, the variable majorForm will be empty because the context of your expression is the root node (non-existent node in the space above the document element), which does not have a @MAJORFORM attribute.

You would need to change it to:

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:output method="xml" indent="yes"/>
  <xsl:variable name="majorForm" select="/*/@MAJORFORM"/>

In your second example, the template matching /* the context is the document element, REPORT, which does have an attribute @MAJORFORM.

However, you are attempting to specify the parameter mainform but the template matching SALES/SUBJECT has a parameter called mainForm (note the capitalization of the letter "F").

Change it to the following:

  <xsl:template match="/*">
    <xsl:copy>
      <xsl:variable name="majorForm" select="@MAJORFORM"/>
      <xsl:apply-templates select="SALES">
        <xsl:with-param name="mainForm" select="$majorForm"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

You could achieve the same output and simplify things with the following stylesheet:

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0"> 
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="REPORT">
        <xsl:copy>           
            <xsl:apply-templates select="SALES/SUBJECT/@LATITUDE">
                <xsl:with-param name="mainForm" select="@MAJORFORM"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="SALES/SUBJECT/@LATITUDE">
        <xsl:param name="mainForm"/>
        <form>
            <formName>
                <xsl:value-of select="$mainForm"/>
            </formName>
        </form>
    </xsl:template>

</xsl:stylesheet>

Upvotes: 1

Related Questions