
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%7Dset-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%27%7D) *** lxml.etree.XPathEvalError: Invalid expressio node.xpath("""$destination_url""", namespaces={'xsl':'http://www.w3.org/1999/XSL/Transform%27%7D) *** lxml.etree.XPathEvalError: Undefined variable node.xpath("""/xsl:$destination_url""", namespaces={'xsl':'http://www.w3.org/1999/XSL/Transform%27%7D) *** lxml.etree.XPathEvalError: Invalid expression node.xpath("""<xsl:value-of select="$destination_url">""", namespaces={'xsl':'http://www.w3.org/1999/XSL/Transform%27%7D) *** lxml.etree.XPathEvalError: Invalid expression
I'm lost now! Any suggestions greatly appreciated!
Cheers,
aid