tags:

views:

232

answers:

2

Hi,

I have a stylesheet that makes use of exslt:dynamic module and more precisely, it only uses the evaluate function. I know the XslCompiledTransform from .NET 2.0 does not implement this module (just like the ExslTransform from Mvp.Xml).

Any idea how to solve this problem?

+1  A: 

Mvp.Xml includes an similar extension function dyn2:dynamic.

object dyn2:evaluate (node-set, string, string?)

The dyn2:evaluate function evaluates a string as an XPath expression and returns the resulting value, which might be a boolean, number, string, node set, result tree fragment or external object.

First node-set argument provides a context node (the first node in the passed node-set), such that selection paths are evaluated relative to it. Second string argument is the XPath expression to be evaluated. Third optional string argument provides namespace bindings to be used to resolve namespace prefixes in the XPath expression. Namespaces are defined in the XML style, as a space separated list of namespace declaration attributes.

All namespace prefixes that are in scope for the context node (or its parent node if the context node isn't element node) can be referenced in the evaluated XPath expression. Note though that relying on namespace prefixes defined in the source XML is very unreliable. We encourage users to define namespace bindings explicitly in the third argument instead.

If the node-set passed as first argument is empty (no context node) or the expression string passed as the second argument is an invalid XPath expression (including an empty string), this function returns an empty string. Malformed namespace declarations in the third argument are ignored.

Note that this function is more limited than EXSLT's dyn:evaluate() function. More formally:

  • No context position and context size information is available.
  • No variable bindings - this function is unable to evaluate XPath expressions, which contain variable references!
  • No custom extension functions - only core XPath functions and all extension functions, supported by EXSLT.NET are available.
  • No current node, so the expression cannot contain the current() function calls.
  • No key definition information available, so the expression cannot contain the key() function calls.
  • No custom decimal format definitions are avilable, so the expression cannot contain the fomat-number() function calls that refer to a definition.

There is no 1 parameter version of that extension function, because it would have no context to evaluate the expression in.

This following extension is a 1 parameter version of evaluate. The evaluation context is fixed.

public class MyExtension
{
    IXPathNavigable context;
    public MyExtension( IXPathNavigable context )
    {
        this.context = context;
    }
    public object Evaluate( string expression )
    {
        return context.CreateNavigator().Evaluate( expression );
    }
}

XsltArgumentList args = new XsltArgumentList();
args.AddExtensionObject("my-ext", new MyExtension(doc));

xslt.Transform( doc, args output );
Lachlan Roche
Yes I have tried using the GDNDynamicExtension object in my XslArgumentList's extension objects, but I get an error telling me that no method evaluate with one parameter could be found.
Alex
You did put me on the right track, I just has to make some minor changes to make it work. I'll post my extension object in case someone else needs it. Thank you very much for your help.
Alex
+1  A: 

Here is my final extension object to use the one parameter evaluate function from exslt:

public class DynamicExtension
{
    XPathNavigator _context;
    IXmlNamespaceResolver _namespaceResolver;

    public DynamicExtension(XPathNavigator p_context, IXmlNamespaceResolver p_namespaceResolver)
    {
        _context = p_context;
        _namespaceResolver= p_namespaceResolver;
    }

    public object evaluate(string p_expression)
    {
        return _context.Evaluate(p_expression, _namespaceResolver);
    }
}

The IXmlNameSpaceResolver passed to the constructor is an instance of XmlNamespaceManager. I needed it since the nodes in my xml have namespace prefix. It is important that the case of the evaluate method match the case used in the xsl. Finally, the interface IXPathNavigable has no Evaluate function, I had to pass a XPathNavigator object (gotten from my XmlDocument.CreateNavigator method).

Alex