XPATH Challenge - Want to Copy an Inner Element
I am struggling with what should be a simple XSL: Copy the updateResponse from the message below (note: I need XPATH 1.0 syntax for my integration system compatibility):
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:enterprise.soap.sforce.com" xmlns:n="urn:enterprise.soap.sforce.com">
<soapenv:Body>
<updateResponse>
<result>
<id>001S000000J1Bu0IAF</id>
<success>true</success>
</result>
</updateResponse>
</soapenv:Body>
</soapenv:Envelope>
I simply want the result structure to be:
<updateResponse xmlns="urn:enterpri开发者_开发知识库se.soap.sforce.com">
<result>
<id>001S000000J1Bu0IAF</id>
<success>true</success>
</result>
</updateResponse>
I am able to copy the soap objects, but am unsuccessful in copying the children of the soapenv:Body element. The first copy-of works for Body, but the second does not resolve the XPATH. My XMLSPY tool xpath query editor says the xpath is valid, but the XSL does not resolve.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:urn="enterprise.soap.sforce.com" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:namespace-alias stylesheet-prefix="soapenv" result-prefix="foo"/>
<xsl:template match="/">
<xsl:apply-templates select="/soapenv:Envelope/soapenv:Body/urn:updateResponse"/>
</xsl:template>
<xsl:template match="/soapenv:Envelope/soapenv:Body/urn:updateResponse">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
Your namespaces are mismatched between your data and your stylesheet, that seems to be the only problem.
In your stylesheet document, change this:
xmlns:urn="enterprise.soap.sforce.com"
to this:
xmlns:urn="urn:enterprise.soap.sforce.com"
Then it will match the declared namespaces in your original input file.
This stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:template match="/soapenv:Envelope/soapenv:Body//*">
<xsl:element name="{local-name()}"
namespace="urn:enterprise.soap.sforce.com">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Output:
<updateResponse xmlns="urn:enterprise.soap.sforce.com">
<result>
<id>001S000000J1Bu0IAF</id>
<success>true</success>
</result>
</updateResponse>
Note: First, the namespace declaration in your stylesheet is wrong. It should be xmlns:urn="urn:enterprise.soap.sforce.com"
. Second, for an exact result you need to strip in scope namespaces (there are three: xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
, xmlns="urn:enterprise.soap.sforce.com"
(default), and xmlns:n="urn:enterprise.soap.sforce.com
)
The namespaces in this document are weird; you have xmlns and xmlns:n both assigned to the same namespace. It looks like //soapenv:updateResponse
should work. Have you tried that?
精彩评论