def get_variable_from_xsl(variable_name, xsl):xpath_results = xsl.xpath("//xsl:variable[@name=$name]", name=variable_name,namespaces={'xsl':'http://www.w3.org/1999/XSL/Transform'})for xpath_result in xpath_results:if xpath_result.get('name') == variable_name:for xpath_child in xpath_result.getchildren():if 'select' in xpath_child.keys():return xpath_child.get('select')return Nonedestination_url = get_variable_from_xsl('destination_url', xsl)print(f"destination_url = {destination_url}")
destination_url = 'https://my.domain.example.com/'
Adrian Bool schrieb am 10.04.19 um 10:49:
> 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.
Well, XSL is XML, so you can always post-process the XSL document after
parsing it as XML, before you pass it into the XSLT() constructor.
> 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" />
I don't think I've ever tried this myself in lxml. I guess I would have
expected value="{$destination_url}" rather than the plain variable
reference here. Can't say how XSLT is meant to deal with this.
> </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.
Did you try looking it up in the XSL document via XPath? Something like
.xpath("//xsl:variable[@name=$name]", name="destination_url")
(plus namespaces)
Stefan
_________________________________________________________________
Mailing list for the lxml Python XML toolkit - http://lxml.de/
lxml@lxml.de
https://mailman-mail5.webfaction.com/listinfo/lxml