XSLT can do many things, and now it can be a SOAP client too. To demonstrate the extension here's a stylesheet that makes a call to the Amazon webservice looking for books on XSLT:
The XSLT
Here's the XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://saxon.sf.net/" xmlns:soap="net.sf.kernow.soapextension.SOAPExtension" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" version="2.0" exclude-result-prefixes="xs">
<xsl:output indent="yes" />
<xsl:param name="endpoint" select="'http://soap.amazon.com/onca/soap?Service=AWSECommerceService'" as="xs:string" />
<xsl:variable name="request">
<soapenv:Envelope xmlns:ns="http://webservices.amazon.com/AWSECommerceService/2007-05-14">
<soapenv:Body>
<ns:ItemSearch>
<ns:AWSAccessKeyId>[my awsaccessid - insert your own]</ns:AWSAccessKeyId>
<ns:Shared>
<ns:Keywords>XSLT</ns:Keywords>
<ns:SearchIndex>Books</ns:SearchIndex>
</ns:Shared>
</ns:ItemSearch>
</soapenv:Body>
</soapenv:Envelope>
</xsl:variable>
<xsl:template match="/" name="main">
<xsl:apply-templates select="saxon:parse(soap:soapRequest($request, $endpoint))" mode="process-SOAP-message" />
</xsl:template>
<xsl:template match="/" mode="process-SOAP-message">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
<xsl:output indent="yes" />
<xsl:param name="endpoint" select="'http://soap.amazon.com/onca/soap?Service=AWSECommerceService'" as="xs:string" />
<xsl:variable name="request">
<soapenv:Envelope xmlns:ns="http://webservices.amazon.com/AWSECommerceService/2007-05-14">
<soapenv:Body>
<ns:ItemSearch>
<ns:AWSAccessKeyId>[my awsaccessid - insert your own]</ns:AWSAccessKeyId>
<ns:Shared>
<ns:Keywords>XSLT</ns:Keywords>
<ns:SearchIndex>Books</ns:SearchIndex>
</ns:Shared>
</ns:ItemSearch>
</soapenv:Body>
</soapenv:Envelope>
</xsl:variable>
<xsl:template match="/" name="main">
<xsl:apply-templates select="saxon:parse(soap:soapRequest($request, $endpoint))" mode="process-SOAP-message" />
</xsl:template>
<xsl:template match="/" mode="process-SOAP-message">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
The actual request here is written directly in the variable $request, but it could easily be pulled in using doc() or created within the stylesheet
The function is in the package
net.sf.kernow.soapextension.SOAPExtension and the method is soap:soapRequest($request, $endpoint)). It's included with Kernow so if you run this stylesheet from within Kernow it should just work - otherwise you'll need to ensure the class on the classpath along with Saxon.The function returns a String which is turned into an XML document by calling
saxon:parse(). Calling apply-templates on this will make Saxon look for the root-matching template, so to prevent an endless loop the mode is needed.The Extension class
Here's the Java:
package net.sf.kernow.soapextension.SOAPExtension;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLConnection;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import net.sf.saxon.om.NodeInfo;
/**
* Enables the calling of SOAP based web services from XSLT.
* @author Andrew Welch
*/
public class SOAPExtension {
public static final String ENCODING = "UTF-8";
public static final String CONTENT_LENGTH = "Content-Length";
public static final String CONTENT_TYPE = "Content-Type";
public static final String CONTENT_TYPE_VALUE = "text/xml; charset=utf-8";
public static final String SOAPACTION = "SOAPAction";
public static final String POST = "POST";
public static String soapRequest(NodeInfo requestXML, String endpoint) {
String result = makeCall(transformToString(requestXML), endpoint);
return result;
}
public static String soapRequest(String requestXML, String endpoint) {
String result = makeCall(requestXML, endpoint);
return result;
}
private static String transformToString(NodeInfo sourceXML) {
StringWriter sw = new StringWriter();
try {
TransformerFactory tFactory = new net.sf.saxon.TransformerFactoryImpl();
Transformer transformer = tFactory.newTransformer();
transformer.transform(sourceXML, new StreamResult(sw));
} catch (TransformerConfigurationException ex) {
ex.printStackTrace();
} catch (TransformerException ex) {
ex.printStackTrace();
}
return sw.toString();
}
private static String makeCall(String requestXML, String endpoint) {
String SOAPUrl = endpoint;
StringBuilder responseBuf = new StringBuilder();
try {
// Create the connection to the endpoint
URL url = new URL(SOAPUrl);
URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) connection;
byte[] b = requestXML.getBytes(ENCODING);
// Set the appropriate HTTP parameters.
httpConn.setRequestProperty(CONTENT_LENGTH, String.valueOf(b.length));
httpConn.setRequestProperty(CONTENT_TYPE, CONTENT_TYPE_VALUE);
httpConn.setRequestProperty(SOAPACTION, "");
httpConn.setRequestMethod(POST);
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
// Send the the request
OutputStream out = httpConn.getOutputStream();
out.write(b);
out.flush();
// Read the response and write it to the response buffer.
InputStreamReader isr = new InputStreamReader(httpConn.getInputStream());
BufferedReader in = new BufferedReader(isr);
String line;
while ((line = in.readLine()) != null) {
responseBuf.append(line);
}
in.close();
} catch (ProtocolException ex) {
ex.printStackTrace();
return error(ex.getMessage());
} catch (MalformedURLException ex) {
ex.printStackTrace();
return error(ex.getMessage());
} catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
return error(ex.getMessage());
} catch (IOException ex) {
ex.printStackTrace();
return error(ex.getMessage());
}
return responseBuf.toString();
}
private static String error(String msg) {
return "" + msg + " ";
}
}
The class accepts requests as either NodoInfo or Strings. If the request is a NodeInfo it's converted to a String using an indentity transform (which you get by calling newTransfomer() without a stylesheet - it's a highly optimized way of serializing XML using Saxon).
An HTTP connection is opened to the endpoint and the request made, and the whole result SOAP message (which is still a String) returned to the transform. The response could be parsed and a NodeInfo returned instead, which would remove the need for
saxon:parse() in the transform (but as we're already tightly coupled to Saxon we may as well not rewrite that). It's worth noting that the "SOAPAction" header is required - I originally didn't set this (in Kernow 1.5.0.5 and below) but some web services seem to require it - read hereIf any exceptions are thrown, the exception message is returned to the transform wrapped in
<error></error> to allow the transform to deal with it.The Result
Running the above transform in the standalone tab of Kernow gives this result - some classics there:
<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Body>
<ItemSearchResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2007-05-14">
<OperationRequest>
<HTTPHeaders>
<Header Name="UserAgent" Value="Jakarta Commons-HttpClient/3.0" />
</HTTPHeaders>
<RequestId>1HXAKAY8C9M9H4P1906T</RequestId>
<Arguments>
<Argument Name="Service" Value="AWSECommerceService" />
</Arguments>
<RequestProcessingTime>0.151901006698608</RequestProcessingTime>
</OperationRequest>
<Items>
<Request>
<IsValid>True</IsValid>
</Request>
<TotalResults>85</TotalResults>
<TotalPages>9</TotalPages>
<Item>
<ASIN>0596005792</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0596005792%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0596005792%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Geoff Coffey</Author>
<Author>Susan Prosser</Author>
<Manufacturer>O'Reilly Media, Inc.</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>FileMaker Pro 8: The Missing Manual</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0596007647</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0596007647%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0596007647%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Elliotte Rusty Harold</Author>
<Author>W. Scott Means</Author>
<Manufacturer>O'Reilly Media, Inc.</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>XML in a Nutshell, Third Edition</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0764569090</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0764569090%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0764569090%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Michael Kay</Author>
<Manufacturer>Wrox</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>XSLT 2.0 Programmer's Reference (Programmer to Programmer)</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0596009747</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0596009747%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0596009747%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Salvatore Mangano</Author>
<Manufacturer>O'Reilly Media, Inc.</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>XSLT Cookbook, Second Edition (Cookbooks (O'Reilly))</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0470087889</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0470087889%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0470087889%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Eric van der Vlist</Author>
<Author>Danny Ayers</Author>
<Author>Erik Bruchez</Author>
<Author>Joe Fawcett</Author>
<Author>Alessandro Vernet</Author>
<Manufacturer>Wrox</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>Professional Web 2.0 Programming (Wrox Professional Guides)</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0672323184</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0672323184%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0672323184%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Michiel van Otegem</Author>
<Manufacturer>Sams</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>Sams Teach Yourself XSLT in 21 Days</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>1556220863</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=1556220863%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/1556220863%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Scott Driza</Author>
<Manufacturer>Wordware Publishing, Inc.</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>Word 2003 Document Automation with VBA, XML, XSLT, and Smart Documents (Wordware Applications Library)</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0596003277</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0596003277%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0596003277%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Michael Fitzgerald</Author>
<Manufacturer>O'Reilly Media, Inc.</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>Learning XSLT</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0596000537</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0596000537%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0596000537%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Doug Tidwell</Author>
<Manufacturer>O'Reilly Media, Inc.</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>Xslt</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0596006349</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0596006349%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0596006349%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Priscilla Walmsley</Author>
<Manufacturer>O'Reilly Media, Inc.</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>XQuery</Title>
</ItemAttributes>
</Item>
</Items>
</ItemSearchResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
<SOAP-ENV:Body>
<ItemSearchResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2007-05-14">
<OperationRequest>
<HTTPHeaders>
<Header Name="UserAgent" Value="Jakarta Commons-HttpClient/3.0" />
</HTTPHeaders>
<RequestId>1HXAKAY8C9M9H4P1906T</RequestId>
<Arguments>
<Argument Name="Service" Value="AWSECommerceService" />
</Arguments>
<RequestProcessingTime>0.151901006698608</RequestProcessingTime>
</OperationRequest>
<Items>
<Request>
<IsValid>True</IsValid>
</Request>
<TotalResults>85</TotalResults>
<TotalPages>9</TotalPages>
<Item>
<ASIN>0596005792</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0596005792%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0596005792%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Geoff Coffey</Author>
<Author>Susan Prosser</Author>
<Manufacturer>O'Reilly Media, Inc.</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>FileMaker Pro 8: The Missing Manual</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0596007647</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0596007647%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0596007647%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Elliotte Rusty Harold</Author>
<Author>W. Scott Means</Author>
<Manufacturer>O'Reilly Media, Inc.</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>XML in a Nutshell, Third Edition</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0764569090</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0764569090%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0764569090%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Michael Kay</Author>
<Manufacturer>Wrox</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>XSLT 2.0 Programmer's Reference (Programmer to Programmer)</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0596009747</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0596009747%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0596009747%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Salvatore Mangano</Author>
<Manufacturer>O'Reilly Media, Inc.</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>XSLT Cookbook, Second Edition (Cookbooks (O'Reilly))</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0470087889</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0470087889%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0470087889%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Eric van der Vlist</Author>
<Author>Danny Ayers</Author>
<Author>Erik Bruchez</Author>
<Author>Joe Fawcett</Author>
<Author>Alessandro Vernet</Author>
<Manufacturer>Wrox</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>Professional Web 2.0 Programming (Wrox Professional Guides)</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0672323184</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0672323184%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0672323184%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Michiel van Otegem</Author>
<Manufacturer>Sams</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>Sams Teach Yourself XSLT in 21 Days</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>1556220863</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=1556220863%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/1556220863%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Scott Driza</Author>
<Manufacturer>Wordware Publishing, Inc.</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>Word 2003 Document Automation with VBA, XML, XSLT, and Smart Documents (Wordware Applications Library)</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0596003277</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0596003277%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0596003277%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Michael Fitzgerald</Author>
<Manufacturer>O'Reilly Media, Inc.</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>Learning XSLT</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0596000537</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0596000537%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0596000537%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Doug Tidwell</Author>
<Manufacturer>O'Reilly Media, Inc.</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>Xslt</Title>
</ItemAttributes>
</Item>
<Item>
<ASIN>0596006349</ASIN>
<DetailPageURL>http://www.amazon.com/gp/redirect.html%3FASIN=0596006349%26tag=ws%26lcode=sp1%26cID=2025%26ccmID=165953%26location=/o/ASIN/0596006349%253FSubscriptionId=[my awsaccessid - insert your own]</DetailPageURL>
<ItemAttributes>
<Author>Priscilla Walmsley</Author>
<Manufacturer>O'Reilly Media, Inc.</Manufacturer>
<ProductGroup>Book</ProductGroup>
<Title>XQuery</Title>
</ItemAttributes>
</Item>
</Items>
</ItemSearchResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Making it more useful...
If you want to make several calls using different arguments, you can turn the request variable into a function:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://saxon.sf.net/" xmlns:soap="net.sf.kernow.soapextension.SOAPExtension" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:func="func" version="2.0" exclude-result-prefixes="xs">
<xsl:output indent="yes" />
<xsl:param name="endpoint" select="'http://soap.amazon.com/onca/soap?Service=AWSECommerceService'" as="xs:string" />
<xsl:function name="func:request" as="element()">
<xsl:param name="keywords" as="xs:string+" />
<xsl:param name="searchIndex" as="xs:string" />
<soapenv:Envelope xmlns:ns="http://webservices.amazon.com/AWSECommerceService/2007-05-14">
<soapenv:Body>
<ns:ItemSearch>
<ns:AWSAccessKeyId>[my awsaccessid - insert your own]</ns:AWSAccessKeyId>
<ns:Shared>
<ns:Keywords><xsl:value-of select="$keywords" /></ns:Keywords>
<ns:SearchIndex><xsl:value-of select="$searchIndex" /></ns:SearchIndex>
</ns:Shared>
</ns:ItemSearch>
</soapenv:Body>
</soapenv:Envelope>
</xsl:function>
<xsl:template match="/" name="main">
<xsl:variable name="request" select="func:request('XSLT', 'Books')" as="element()" />
<xsl:apply-templates select="saxon:parse(soap:soapRequest($request , $endpoint))" mode="process-SOAP-message" />
</xsl:template>
<xsl:template match="/" mode="process-SOAP-message">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
<xsl:output indent="yes" />
<xsl:param name="endpoint" select="'http://soap.amazon.com/onca/soap?Service=AWSECommerceService'" as="xs:string" />
<xsl:function name="func:request" as="element()">
<xsl:param name="keywords" as="xs:string+" />
<xsl:param name="searchIndex" as="xs:string" />
<soapenv:Envelope xmlns:ns="http://webservices.amazon.com/AWSECommerceService/2007-05-14">
<soapenv:Body>
<ns:ItemSearch>
<ns:AWSAccessKeyId>[my awsaccessid - insert your own]</ns:AWSAccessKeyId>
<ns:Shared>
<ns:Keywords><xsl:value-of select="$keywords" /></ns:Keywords>
<ns:SearchIndex><xsl:value-of select="$searchIndex" /></ns:SearchIndex>
</ns:Shared>
</ns:ItemSearch>
</soapenv:Body>
</soapenv:Envelope>
</xsl:function>
<xsl:template match="/" name="main">
<xsl:variable name="request" select="func:request('XSLT', 'Books')" as="element()" />
<xsl:apply-templates select="saxon:parse(soap:soapRequest($request , $endpoint))" mode="process-SOAP-message" />
</xsl:template>
<xsl:template match="/" mode="process-SOAP-message">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
And that's it, a nice easy way to access SOAP based web services in XSLT.
top