Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use a Dynamic xPath expression in a xslt style sheet?

Tags:

xml

xslt

xpath

ant

I'd like to use the value of an xslt parameter in an xpath expression. Specifically, as part of a not() call in an <xsl:if expression.

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- my_param contains a string '/foo/bar', passed in from ant -->
    <!-- the 'no' is just a default value -->
    <xsl:param name="my_param">no</xsl:param>
    <xsl:variable name="var_myparam" select="$my_param" />
    <!-- ... -->

    <!-- this works -->
    <xsl:if test="not(/foo/bar)" /> <!-- expression returns boolean true -->
        <!-- ... -->
    </xsl:if>

    <!-- I can't figure out how to do this the right way -->
    <!-- None of these appear to work -->
    <xsl:if test="not($var_myparam)" /> <!-- expression returns boolean false -->
        <!-- ... -->
    </xsl:if>       
    <xsl:if test="not({$var_myparam})" /> <!-- complains Required attribute 'test' is missing -->
        <!-- ... -->
    </xsl:if>       
    <xsl:if test="not({$myparam})" />   <!-- complains Required attribute 'test' is missing -->
        <!-- ... -->
    </xsl:if>       
    <xsl:if test="not($myparam)" />     <!-- expression returns boolean false -->
        <!-- ... -->
    </xsl:if>       

</xsl:transform>

I'm a little unclear on what the correct syntax is for creating a dynamic xpath expression in an xslt style sheet. I'm also a little fuzzy on the difference between a paramater, a variable, and how expanstion of both works. For example, with parameters, I know that sometimes I need the brackets, and sometimes I don't.

<!-- when creating an element, it seems I need brackets -->
<xsl:element name="{$my_param}" />

<!-- when selecting an element value for the output stream, no brackets are needed -->
<xsl:value-of select="$my_param"/>

Any general/specific help would be greatly appreciated.

like image 236
Alan Storm Avatar asked Oct 11 '09 19:10

Alan Storm


People also ask

How to perform dynamic XPath evaluation in XSLT?

Dynamic XPath evaluation is not possible in pure XSLT 1.0 or 2.0. Unfortunately, very few XSLT 1.0 processors implement dyn:evaluate (). II. Process the XML document with XSLT and generate a new XSLT file that contains the XPath expressions -- then execute the newly-generated transformation.

What is XPath?

What is XPath? 1 XPath is a syntax for defining parts of an XML document 2 XPath uses path expressions to navigate in XML documents 3 XPath contains a library of standard functions 4 XPath is a major element in XSLT and in XQuery 5 XPath is a W3C recommendation More ...

Is it possible to use Dyn evaluate () in XSLT?

Unfortunately, very few XSLT 1.0 processors implement dyn:evaluate (). II. Process the XML document with XSLT and generate a new XSLT file that contains the XPath expressions -- then execute the newly-generated transformation.

What is an XSLT variable?

Definition of XSLT Variable. XSLT variable is defined as special tags used to declare a local or global variable that we make use of to store any values. The declared variables are referenced within an Xpath expression. Once it is set we cannot overwrite or update the variables. The scope of the element is done by the element that contains it.


2 Answers

Check out http://www.exslt.org/. Specifically look at the dynamic:evaluate module.

like image 108
CMN Avatar answered Sep 19 '22 11:09

CMN


XSLT doesn't support dynamic evaluation of XPath - that's why you need to use an extension function like EXSLT's evaluate to do it.

If you don't want to use extension functions (and there are good reasons not to), another possibility is to query the input document's DOM before you execute the transform, and pass the node-set into the transform as a parameter.

Edit

About those curly braces: Those are attribute value templates (AVTs). These are semantically equivalent in an XSLT transform:

<foo>
   <xsl:attribute name="bar">
      <xsl:value-of select="XPathExpression"/>
   </xsl:attribute>
</foo>

<foo bar="{XPathExpression}"/>

The second is just a shortcut for the first.

About variables and parameters: Syntactically, there's no difference between a variable and a parameter; anywhere you reference $foo in an XPath expression it will work the same whether foo is defined by xsl:variable or xsl:param.

The difference between the two is how they get populated. Variables are populated in the xsl:variable declaration. Parameters are declared in a named template using xsl:param, but they're populated by whatever calls the named template, using xsl:with-param, e.g.:

<xsl:call-template name="foo">
   <xsl:with-param name="bar" select="XPathExpression"/>
</xsl:call-template>

<xsl:template name="foo">
   <xsl:param name="bar"/>
   ...

The big honking exception to this is parameters that are a child of xsl:stylesheet. There's no way to populate those parameters within the transform; those are populated externally, by whatever (environment-specific) mechanism is invoking the transform.

A pretty common use case is making up for the fact that XSLT doesn't have a system date function. So you'll see something like:

<xsl:stylesheet ...
   <xsl:param name="system-date"/>
   ...

and then, when invoking the transform, something like this (in C#):

XsltArgumentList args = new XsltArgumentList();
args.AddParam("system-date", "", DateTime.Now.ToString("s"));
xslt.Transform(input, args, result);
like image 33
Robert Rossney Avatar answered Sep 18 '22 11:09

Robert Rossney