RE: external variables

Subject: RE: external variables
From: "Maxime Levesque" <maximel@xxxxxxxxxxxxxx>
Date: Tue, 20 Jul 1999 11:30:06 -0700
 If your XML is generated, you can always generate a tag that
just holds the variable value ex.:


... in your xml :
<variable name="browserName" value "aBrowserName"/>
...


... in your xsl :
<xsl:variable name='browserName' expr="variable[@name='browserName']"/>
... now you have your variable ...


 Now, if you want a genericc way to pass state from
java to XT back and forth, continue reading ...


 There is already a mechanism to call java methods from XT,
but if you want to pass some state to XT from outside, I have
not found a way besides using static variables, which is useless
in a concurrent context ...


With a few modifications to XT you can do it.
It invovles passing an instance of ExtensionContext to
an XSLProcessorImpl before processing...


 The built in 'ExtensionContext' (ContextImpl) uses reflection
to call java methods, ours is much less clever ... but
it does the job ... It could be made nicer, but I didn't have time ...

 James Clark might have a much more elegant way of doing this ...



<xsl:stylesheet
  ...
  xmlns:satefullContext="http://www.jclark.com/xt/statefull_java/";  <!-- add
this name space -->
  ...
  >


  <xsl:variable browserName='satefullContext:getBrowserName()'>

  ...
</xsl:stylesheet>


         ... in your java code ...

         final String browserName = "... initialise it here ..."

         ExtensionContext handler = new ExtensionContext() {

            public boolean available(java.lang.String name) {
               return name.equals("getBrowserName");
            }

            public Object call(String name, com.jclark.xsl.om.Node
currentNode, Object[] args) throws
com.jclark.xsl.om.XSLException {


		   /* note : the args will be either

			- ResultFragmentVariantBase (if a string was passed in param)

			- ResultTreeFragment (if a node set was passed in param)

			- numeric (if a number was passed)

			You'll have to do a bit of work if you want to
			play with params, tell me if you're interrested ...
	         */

               if(name.equals("getBrowserName"))
		     return browserName_;
            }
         };



  com.jclark.xsl.sax.XSLProcessorImpl p =
            new com.jclark.xsl.sax.XSLProcessorImpl(aSaxParser, aSaxParser,
handler);


  now the sheets processed with 'p' have acess to the browserName_ java
variable ...
  of course you don't want to reuse this instances of 'p' ...



 Maxime Levesque


 The hacks are below (My appoogies to James Clark for hacking in his code :)


------------------------------ in class :
com.jclark.xsl.sax.ExtensionHandlerImpl ------------------------

   // ADD MEMBER (HACK):
   private ExtensionContext statefullHandler_;

   // HACK BEGIN
   public ExtensionHandlerImpl() {} // explicitely put the no arg
constructor...

   // add this constructor :
   public ExtensionHandlerImpl(ExtensionContext statefullHandler) {
      statefullHandler_ = statefullHandler;

      System.out.println("Will use statefullHandler = " + statefullHandler);

   }
   // HACK END.



  static final private String STATEFULL_JAVA_NS =
"http://www.jclark.com/xt/statefull_java/";;


  // change the following method :

  public ExtensionContext createContext(String namespace) throws
XSLException {

    // HACK BEGIN :
    if (namespace.startsWith(STATEFULL_JAVA_NS))
       return statefullHandler_;
    // HACK END.

    if (namespace.startsWith(JAVA_NS)) {
      System.out.println("Will use built int handler");
      try {
	return new
ContextImpl(Class.forName(namespace.substring(JAVA_NS.length())));
      }
      catch (ClassNotFoundException e) { }
    }

    return null;
  }

------------------------------ in class :
com.jclark.xsl.sax.XSLProcessorImpl ------------------------

   // HACK BEGIN :

  public XSLProcessorImpl(Parser sourceParser, Parser sheetParser,
com.jclark.xsl.expr.ExtensionContext extensionContext) {
    this.sourceParser = sourceParser;
    this.sheetParser = sheetParser;
    sourceLoader = new XMLProcessorImpl(sourceParser);
    if (sourceParser == sheetParser)
      sheetLoader = sourceLoader;
    else
      sheetLoader = new XMLProcessorImpl(sheetParser);

    // this is the modified line :
    engine = new EngineImpl(sheetLoader, new
ExtensionHandlerImpl(extensionContext));

    sheet = null;
  }

  public XSLProcessorImpl(Parser sourceParser, Parser sheetParser) {
     this(sourceParser, sheetParser, null);
  }

   // HACK END.

------------------------------------------------------


 Maxime Levesque


> -----Original Message-----
> From: owner-xsl-list@xxxxxxxxxxxxxxxx
> [mailto:owner-xsl-list@xxxxxxxxxxxxxxxx]On Behalf Of Jon Smirl
> Sent: Friday, July 16, 1999 12:48 PM
> To: XSLList
> Subject: external variables
>
>
> I am doing server-side XSL processing where I have an XSL stylesheet and
> some in-memory, generated XML. The transformation is to HTML. I would like
> the be able to add some if-then coding to my XSL depending on the browser
> type.
>
> What is the right way for getting to information like this?
> Should I set an
> environment variable and use system-properties() to access it, or
> is there a
> better way I can't figure out? I'm trying to set up for using XSchema so I
> want to avoid using DTD's. I'm using James Clark's XT/XP.
>
> Also, how would this work from a command like app? I would like to set
> variables on the command line and then access them from the XSL sheet.
>
> Jon Smirl
> jonsmirl@xxxxxxxxxxxx
>
>
>
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
>


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread