Replace an XML element value using XSLT
The aim is to take a document, look for a specific element (by local name and URI rather than name including prefix) and replace its value.
Where is this useful? Imagine a gateway protecting an internal web service. If that web service is WS-A enabled, it therefores has a wsa:From field which contains its internal URI. Obviously the gateway abstracts the internal service from what is seen outside as a ‘virtual’ or ‘logical’ service. One therefore needs to update the wsa:From field to reflect an external URI.
Sample XML:
<?xml version=”1.0″ encoding=”UTF-8″?>
<soap12:Envelope xmlns:soap12=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:wsa05=”http://www.w3.org/2005/08/addressing” xmlns:uddi=”urn:uddi-org:api_v2″ xmlns:ns1=”http://ws.samples.engage.bt.com” xsi:schemaLocation=”http://schemas.xmlsoap.org/soap/envelope/ http://schemas.xmlsoap.org/soap/envelope/”>
<soap12:Header>
<wsa05:To>http://somelocation</wsa05:To>
<wsa05:Action>urn:greet</wsa05:Action>
<wsa05:From>
<wsa05:Address>http://internaluri.intra.mycompany.com</wsa05:Address>
</wsa05:From>
</soap12:Header>
<soap12:Body>
<ns1:greet soap12:encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/”>
<in0 xsi:type=”xsd:string”>Philip</in0>
</ns1:greet>
</soap12:Body>
</soap12:Envelope>
The XSL to be applied here is
<?xml version=”1.0″ encoding=”UTF-8″?>
<xsl:stylesheet version=”2.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” xmlns:xs=”http://www.w3.org/2001/XMLSchema” xmlns:fn=”http://www.w3.org/2005/xpath-functions” xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:wsa=”http://www.w3.org/2005/08/addressing”>
<xsl:output method=”xml” version=”1.0″ encoding=”UTF-8″ indent=”yes”/>
<xsl:variable name=”fromVirtualUri”>http://virtualFromValue</xsl:variable>
<xsl:template match=”node()|@*”>
<xsl:copy>
<xsl:choose>
<xsl:when test=”local-name()=’Address'”>
<xsl:if test=”namespace-uri()=’http://www.w3.org/2005/08/addressing'”>
<xsl:value-of disable-output-escaping=”yes” select=”$fromVirtualUri”></xsl:value-of>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select=”@*|*|processing-instruction()|comment()|text()”>
<xsl:with-param name=”virtualUri”></xsl:with-param>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>