Re: Q on applying dyn:valuate to result tree fragment

Hermann Stamm-Wilbrandt <[email protected]> Sat, 28 Nov 2009 01:23:41 +0100
Newsgroups gmane.text.xml.xslt.extensions
Message-ID <OF8E7A3353.0C63863B-ONC125767C.00021BC2-C125767C.00022AE7@de.ibm.com>
Encapsulating the <xsl:for-each> in a function is probably the best
way to deal with this.

<xsl:copy-of select="dyn:applyXpathToRTF(
                     concat($respPath,$dynPath), $urlResponse)"/>
...
...
  <func:function name="dyn:applyXpathToRTF">
    <xsl:param name="xpathString"/>
    <xsl:param name="RTF"/>
    <func:result>
      <xsl:for-each select="exslt:node-set($RTF)">
        <xsl:copy-of select="dyn:evaluate($xpathString)"/>>
      </xsl:for-each>
    </func:result>
  </func:function>


Mit besten Gruessen / Best wishes,

Hermann Stamm-Wilbrandt
Developer, XML Compiler
WebSphere DataPower SOA Appliances
----------------------------------------------------------------------
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294


                                                                           
             Hermann                                                       
             Stamm-Wilbrandt/G                                             
             ermany/IBM@IBMDE                                           To 
             Sent by:                  [email protected]                      
             exslt-bounces@lis                                          cc 
             ts.fourthought.co                                             
             m                                                     Subject 
                                       Re: [exslt] Q on applying           
                                       dyn:valuate to result tree fragment 
             11/24/2009 08:48                                              
             AM                                                            
                                                                           
                                                                           
                                                                           
                                                                           





Hello,

after realizing that the <xsl:apply-templates> in below email
was used for copying purposes only I tried below simplification
(replace it by just <xsl:copy-of>) and it still works.

The question whether the same can be achieved without <xsl:for-each>
remains ...


...
    <xsl:variable name="respPath" select="'/url-open/response'"/>
    <xsl:variable name="dynPath" select="'/RatesResponse/Message'"/>


    <xsl:variable name="dyn">
      <xsl:for-each select="exslt:node-set($urlResponse)">
        <xsl:copy-of select="dyn:evaluate(concat($respPath,$dynPath))"/>
      </xsl:for-each>
    </xsl:variable>

    <xsl:copy-of select="$dyn"/>
...


Mit besten Gruessen / Best wishes,

Hermann Stamm-Wilbrandt
Developer, XML Compiler
WebSphere DataPower SOA Appliances
----------------------------------------------------------------------
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
----- Forwarded by Hermann Stamm-Wilbrandt/Germany/IBM on 11/24/2009 08:42
AM -----

             Hermann
             Stamm-Wilbrandt/G
             ermany/IBM@IBMDE                                           To
             Sent by:                  [email protected]
             exslt-bounces@lis                                          cc
             ts.fourthought.co
             m                                                     Subject
                                       [exslt] Q on applying dyn:valuate
                                       to result tree fragment
             11/23/2009 06:12
             PM









Hello,

DataPower XSLT processor provides a (propietary) extension function
"dp:url-open()" allowing to access web services from within stylesheets.

For allowing discussion I commented out that function call and replaced.
it by a variable definition containing the response (full listing at
bottom):
    <xsl:variable name="urlResponse">
      <url-open>
      <responsecode>200</responsecode>
      <content-type>text/xml</content-type>
      <headers>
      <header name="Date">Mon, 23 Nov 2009 09:04:34 GMT</header>
      <header name="Server">Apache/2.2.3 (Red Hat)</header>
      <header name="Last-Modified">Mon, 23 Nov 2009 08:57:36 GMT</header>
      <header name="ETag">"590469-36-450a000"</header>:
      <header name="Content-Type">text/xml</header></headers>
      <response>
      <RatesResponse>
      <Message>msg</Message></RatesResponse></response></url-open>
    </xsl:variable>


Customer wanted to access part of this result tree fragments response with
a dynamic XPATH expression.
    <xsl:variable name="dynPath" select="'/RatesResponse/Message'"/>

This implied the use of "dyn:evaluate()".


I came up with this "solution":
  $urlResponse is a result tree fragment.
- via the xsl:for-each loop this gets the "current node" (1 element loop)
- dyn:evaluate(concat($respPath,$dynPath)) creates XPATH expression
- xsl:apply-templates applies this XPATH
- mode "dynamic" avoids side effects


...
  <xsl:template match="*" mode="dynamic">)
    <xsl:copy-of select="."/>
  </xsl:template>
...
    <xsl:variable name="respPath" select="'/url-open/response'"/>
    <xsl:variable name="dynPath" select="'/RatesResponse/Message'"/>

    <xsl:variable name="dyn">
      <xsl:for-each select="$urlResponse">
        <xsl:copy>
          <xsl:apply-templates mode="dynamic"
            select="dyn:evaluate(concat($respPath,$dynPath))"/>
        </xsl:copy>
      </xsl:for-each>
    </xsl:variable>

    <xsl:copy-of select="$dyn"/>
...


This works fine for DataPower as well as for XALAN XSLT processors.>
My question is just whether there is a XSLT 1.0 solution without the
xsl:for-each trick?
(motivated by this article:
http://www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/200906/msg00070.html


)

$ curl --data-binary @some.xml http://demoip:2051; echo
<?xml version="1.0" encoding="UTF-8"?>
<Message>msg</Message>
$ java -jar xalan.jar -IN some.xml -XSL good.xsl ; echo
<?xml version="1.0" encoding="UTF-8"?><Message xmlns:exslt="
http://exslt.org/common">msg</Message>
$>


=============================================================
$ cat good.xsl
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:dp="http://www.datapower.com/extensions"
  xmlns:dyn="http://exslt.org/dynamic"
  xmlns:exslt="http://exslt.org/common"
  extension-element-prefixes="dp dyn">

  <xsl:output method="xml"/>

  <xsl:template match="*" mode="dynamic">
    <xsl:copy-of select="."/>
  </xsl:template>

  <xsl:template match="/">
    <xsl:variable name="someURL"
select="'http://someIp:somePort/someServlet'"/>
<!--
    <xsl:variable name="urlResponse">
      <dp:url-open
target="{$someURL}" content-type="text/xml"
timeout="120"
response="responsecode">
        <xsl:copy-of select="."/>
</dp:url-open>
</xsl:variable>>
-->
    <xsl:variable name="urlResponse">
      <url-open>
      <responsecode>200</responsecode>
      <content-type>text/xml</content-type>
      <headers>
      <header name="Date">Mon, 23 Nov 2009 09:04:34 GMT</header>
      <header name="Server">Apache/2.2.3 (Red Hat)</header>
      <header name="Last-Modified">Mon, 23 Nov 2009 08:57:36 GMT</header>
      <header name="ETag">"590469-36-450a000"</header>:
      <header name="Content-Type">text/xml</header></headers>
      <response>
      <RatesResponse>
      <Message>msg</Message></RatesResponse></response></url-open>
    </xsl:variable>

    <xsl:variable name="respPath" select="'/url-open/response'"/>>
    <xsl:variable name="dynPath" select="'/RatesResponse/Message'"/>


    <xsl:variable name="dyn">
      <xsl:for-each select="exslt:node-set($urlResponse)">
        <xsl:copy>
          <xsl:apply-templates mode="dynamic"
            select="dyn:evaluate(concat($respPath,$dynPath))"/>
        </xsl:copy>
      </xsl:for-each>
    </xsl:variable>

    <xsl:copy-of select="$dyn"/>
  </xsl:template>

</xsl:stylesheet>
$


Mit besten Gruessen / Best wishes,

Hermann Stamm-Wilbrandt
Developer, XML Compiler
WebSphere DataPower SOA Appliances
----------------------------------------------------------------------
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

_______________________________________________
exslt mailing list
[email protected]
http://www.exslt.org/list

_______________________________________________
exslt mailing list
[email protected]
http://www.exslt.org/list