tags:

views:

155

answers:

2

I am triggering the transformation using a .NET code,

unless I add "EnableDocumentFunction" property to the XSL-Setting, the program throws error saying .. "Usage of Document() function is prohibited",

Actually the program is not editable and a kind of read-only .. is it possible to edit the XSL code itself so that I can use document() function??

The sample XSL and XMLs are Here:
Sample XML :

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
  <xsl:variable name="State_Code_Trn">
    <State In="California" Out="CA"/>
    <State In="CA" Out="CA"/>
    <State In="Texas" Out="TX"/>
    <State In="TX" Out="TX"/>
  </xsl:variable>

  <xsl:template name="testing" match="test_node">
    <xsl:variable name="test_val">
      <xsl:value-of select="."/>
    </xsl:variable>
    <xsl:element name="{name()}">
      <xsl:choose>
      <xsl:when test="document('')/*/xsl:variable[@name='State_Code_Trn']
              /State[@In=$test_val]">
    <xsl:value-of select="document('')/*/xsl:variable[@name='State_Code_Trn']
              /State[@In=$test_val]/@Out"/>
      </xsl:when>
        <xsl:otherwise>
          <xsl:text>Other</xsl:text>
        </xsl:otherwise>
    </xsl:choose>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>



And the sample XML :

<?xml version="1.0" encoding="utf-8"?>
<root>
  <test_node>California</test_node>
  <test_node>CA</test_node>
  <test_node> CA</test_node>
  <test_node>Texas</test_node>
  <test_node>TX</test_node>
  <test_node>CAA</test_node>
  <test_node></test_node>
</root>
+2  A: 

The document() function here is being used to access the XSLT document itself, and extract the contents of the xsl:variable. It is not actually necessary to use the document() function at all in this case.

Because you are using Microsoft.Net here, you should be able to access msxml extension functions for XSLT. Indeed, the relevant namespace for msxml is already defined in the XSLT document

xmlns:msxsl="urn:schemas-microsoft-com:xslt"

This means you will be able to make use of the node-set function to easily access the nodes within State_Code_Tran variable directly. To do this, try changing the existing xsl:choose function to as follows:

   <xsl:choose>
    <xsl:when test="msxsl:node-set($State_Code_Trn)/State[@In=$test_val]">
     <xsl:value-of select="msxsl:node-set($State_Code_Trn)/State[@In=$test_val]/@Out"/>
    </xsl:when>
    <xsl:otherwise>
     <xsl:text>Other</xsl:text>
    </xsl:otherwise>
   </xsl:choose>

This should yield the following output

<root>
<test_node>CA</test_node>
<test_node>CA</test_node>
<test_node>Other</test_node>
<test_node>TX</test_node>
<test_node>TX</test_node>
<test_node>Other</test_node>
<test_node>Other</test_node>
</root>

(Note that you have a space before one of the 'CA's in your original XML, which is why it is coming out as 'Other'. You may want to add some trimming function to cope with this.

Tim C
Hats-off @Tim, Thanks a million :) :))))
infant programmer
+2  A: 

In addition to @Tim-C 's answer, you could use the ext:node-set() extension function, where the "ext" prefix is associated with the EXSLT namespace: "http://exslt.org/common".

This is supported by XslCompiledTransform and will make your XSLT code a little bit more portable, as EXSLT is a standard library of extension functions.

Dimitre Novatchev
Cool. I didn't know XslCompiledTransform supported that. Now, if only it supported XSLT2.0 too, then I would be a happy man...
Tim C
Thanks for ur valuable answer :)
infant programmer