Hi,

I'm trying to extract from data from XSL files on an IBM DataPower system. I can't change the XSLT files - and therefore need to work around their current structure to get the info I need.

I'm doing this from within Python 3.7 using etree.__version__ 4.3.3.

Here are my imports, a dummy XML object and a cutdown version of the XSL file from the IBM system:

    from lxml import etree
    from textwrap import dedent

    xml = etree.XML("""<root></root>""")

    xsl = etree.XML(dedent(
        """<?xml version="1.0"?>
        <xsl:stylesheet version="1.0"  
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform
        xmlns:dp="http://www.datapower.com/extensions"  
        extension-element-prefixes="dp">

        <xsl:template match="node()|@*">
    <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
    
            <xsl:variable name="destination_url">
                <xsl:value-of select="'https://my.domain.example.com/'" />
            </xsl:variable>

            <!--Set the destination URL in the context variable--> 
            <dp:set-variable name="'var://context/mpgw/Destination'" value="$destination_url" />

        </xsl:template>
        </xsl:stylesheet>
        """))
  
My goal is to use lxml to process this file and extract the contents of the DataPower variable 'var://context/mpgw/Destination' - i.e. the contents of the xsl:variable $destination_url - in the above case 'https://my.domain.example.com/'.

I've created an XSLT extension for the "dp:set-variable" element to try to capture this information:

    class MyExtElement(etree.XSLTExtension):
        def execute(self, context, self_node, input_node, output_parent):
            if self_node.tag == '{http://www.datapower.com/extensions}set-variable':
                print(f"Setting variable of name {self_node.get('name')} to value {self_node.get('value')}")

    extensions = { ('http://www.datapower.com/extensions', 'set-variable') : MyExtElement() }
    result = etree.XSLT(xsl, extensions=extensions)(xml)
    print(f"Result: {result}")

When this is being called; instead of the value of destination_url I'm getting the static "$destination_url" string instead - with the output of the above script being:

    Setting variable of name 'var://context/mpgw/Destination' to value $destination_url
    Result: <?xml version="1.0"?>
    <root/>

I am rather suprised that the $destination_url xsl:variable was not being evaluated - does anyone know why this is the case?

Given the above, I've been trying to find a way to access the $destination_url xsl:variable from within my XSLTExtension - but unfortunately with no luck.

Some things I've tried:

* Calling self.process_children(context) within the extension - this just results in an empty list.

* I've used dir() to look through the context, self_node and input_node args to try to find somewhere the variables may be accessible but with no luck.

* I've used deepcopy to clone self_node to get an xpath function on this argument and made some attempts at using xpath to access the xsl variable - all unsuccessful:

    node = deepcopy(self_node)
    node.xpath("""<xsl:value-of select="$destination_url">""")
        *** lxml.etree.XPathEvalError: Invalid expression
    node.xpath("""$destination_url""")
        *** lxml.etree.XPathEvalError: Undefined variable
    node.xpath("""xsl:$destination_url""")
        *** lxml.etree.XPathEvalError: Invalid expression
    node.xpath("""xsl:$destination_url""",
        namespaces={'xsl':'http://www.w3.org/1999/XSL/Transform'})
        *** lxml.etree.XPathEvalError: Invalid expressio
    node.xpath("""$destination_url""",
        namespaces={'xsl':'http://www.w3.org/1999/XSL/Transform'})
        *** lxml.etree.XPathEvalError: Undefined variable
    node.xpath("""/xsl:$destination_url""",
        namespaces={'xsl':'http://www.w3.org/1999/XSL/Transform'})
        *** lxml.etree.XPathEvalError: Invalid expression
    node.xpath("""<xsl:value-of select="$destination_url">""",
        namespaces={'xsl':'http://www.w3.org/1999/XSL/Transform'})
            *** lxml.etree.XPathEvalError: Invalid expression

I'm lost now!  Any suggestions greatly appreciated!

Cheers,

aid