开发者

How can I write an XSLT which preserves namespace references in text elements?

开发者 https://www.devze.com 2023-02-11 05:13 出处:网络
I\'m writing an XSLT which will convert SOAP 1.2 faults to SOAP 1.1 faults. I\'m using XSLT v2.0, and I\'m doing the transformation in Java; probably using Xerces or whatever XML-transformation Java c

I'm writing an XSLT which will convert SOAP 1.2 faults to SOAP 1.1 faults. I'm using XSLT v2.0, and I'm doing the transformation in Java; probably using Xerces or whatever XML-transformation Java comes bundled with. Soap 1.2 faults have pieces that look like this:

<soap12:code xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Value>soap12:Sender</soap12:Value>
  ...
</soap12:code>

But Soap 1.1 faults look like this:

<soap11:Fault xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
  <faultcode>soap11:Server</faultcode>
  ...
</soap11:Fault>

So, the tricky part is that my XSLT needs to generate something like "soap11:server". It needs to refer to the soap11 namespace with whatever appropriate prefix the XSLT engine has chosen. It might be a prefix like "soap11", but it might also be a prefix like "soap" or "ns1", depending on what the input document looked like. Now for attributes and elements, the XSLT engine handles this for you, generating attributes/elements with the correct prefixes. However, it doesn't modify these namespace references when they occur in raw text. Here is the relevant piece of my XSLT:

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:soap11="http://schemas.xmlsoap.org/soap/e开发者_开发问答nvelope/"
    xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"
    exclude-result-prefixes="soap12"
    version="2.0">

    <xsl:template match="soap12:Fault">
        <soap11:Fault>
            <!-- presumably some mapping logic will go here -->
            <faultcode>soap11:Server</faultcode>
            ...
        </soap11:Fault>
    </xsl:template>
    ...
</xsl:stylesheet>

Is there a way to tell XSLT that "soap11:Server" is, in this context, referring to the soap11 namespace?


Your code is correct. You can verify this by running the transformation and:

  1. Looking at the result.

  2. Parsing the result with an XML parser to verify this is a well-formed XML document.


Let's try to sort out whether you are using XSLT 1.0 or XSLT 2.0. You say you're using XSLT 2.0, but you also say that you are using the default XSLT engine in the JDK, which only supports XSLT 1.0.

The question is relevant because XSLT 1.0 allows the transformation engine (in fact, the serializer) to choose what prefixes will be used in the output, whereas XSLT 2.0 is prescriptive about the choice of prefixes (except in the rare cases where the processor has to dream up a prefix from nowhere).

So the answer is: if you're using an XSLT 1.0 engine, as appears to be the case, then the language spec gives you no guarantees about namespace prefixes in the output, though in practice most processors will do the reasonable thing in straightforward cases. If you want a guarantee, you have to move to an XSLT 2.0 processor.

0

精彩评论

暂无评论...
验证码 换一张
取 消