xsl-list
[Top] [All Lists]

Re: [xsl] Possible to Construct a nodeset "internal" to an XSLT?

2008-04-28 14:17:38
On Mon, Apr 28 2008 05:30:18 +0100, ohaya(_at_)cox(_dot_)net wrote:
...
I have a situation where my XSLT needs to dynamically construct a 
nodeset that is "internal" to it (e.g., in a variable or parameter), 
so that it can then use that nodeset in a call out to a webservice 
using an extension function (soap-call()) within the appliance. 

To start with, I have an XML document that can be used as a kind of 
"skeleton", and I can bring that document into the XSLT as a nodeset 
using document(), but then I need to modify the value of some of the 
elements in that nodeset before invoking the soap-call() extension 
function. 
...
As I said above, I'm kind of new to all of this, so I'm wondering: 

- Is there a way to accomplish the above? 
- Also, is there a better approach to accomplishing this? 

With your skeleton document as 'skeleton.xml' and this stylesheet:

------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  version="1.0"
  xmlns:m="urn:sirrus.ws.runtime"
  exclude-result-prefixes="m">

  <xsl:output method="xml"/>

  <xsl:param name="subject"/>
  <xsl:param name="hostname"/>
  <xsl:param name="uri"/>
  
  <xsl:template match="/">
    <xsl:variable name="rtf">
      <xsl:apply-templates select="document('skeleton.xml')" mode="skel"/>
    </xsl:variable>
    <!-- Use soap-call() here, somehow. -->
    <xsl:copy-of select="$rtf"/>
  </xsl:template>

  <xsl:template match="@*|node()" mode="skel">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" mode="skel"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="m:subject/m:id" mode="skel">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:value-of select="$subject"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="m:webServerName" mode="skel">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:value-of select="$hostname"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="m:uri" mode="skel">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:value-of select="$uri"/>
    </xsl:copy>
  </xsl:template>
  
</xsl:stylesheet>
------------------------------------------------------------

as 'soap-call.xsl', then this xsltproc command line:

xsltproc --stringparam hostname foo.whatever.com  --stringparam uri 
"http://services";  --stringparam subject test1 soap-call.xsl soap-call.xsl 

produces a result tree fragment representing your desired output.

If $rtf doesn't work with your soap-call() extension function, then you
may have to convert it to a node-set using the EXSLT node-set() function
(assuming that it's available to you).

It would have been simpler if 'skeleton.xml' was the source document for
the transformation.

A different simplification would be to just put the contents of
'skeleton.xml' as the content of the declaration for $rtf, with the
xsl:value-of instead of your (unused) magic strings.  That's really only
advisable if the skeleton SOAP message isn't going to change very often.

Regards,


Tony Graham                         
Tony(_dot_)Graham(_at_)MenteithConsulting(_dot_)com
Director                                  W3C XSL FO SG Invited Expert
Menteith Consulting Ltd                               XML Guild member
XML, XSL and XSLT consulting, programming and training
Registered Office: 13 Kelly's Bay Beach, Skerries, Co. Dublin, Ireland
Registered in Ireland - No. 428599   http://www.menteithconsulting.com
  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
xmlroff XSL Formatter                               http://xmlroff.org
xslide Emacs mode                  http://www.menteith.com/wiki/xslide
Unicode: A Primer                               urn:isbn:0-7645-4625-2

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>