【问题标题】:How can I avoid the xmlns namespace attribute passing to child elements in XSLT?如何避免将 xmlns 命名空间属性传递给 XSLT 中的子元素?
【发布时间】:2020-10-09 10:35:43
【问题描述】:

我是 XSLT 的新手。下面是我的样式表代码 sn-p,我已经为需求添加了目标命名空间 =“http://tempuri.org/”。但是它作为空字符串值属性(xmlns =“”)被传递给来自...

的子元素
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:tns="http://tempuri.org/" version="1.0">

    <xsl:output encoding="utf-8" indent="yes" method="xml" omit-xml-declaration="yes"/>

    <!-- Stylesheet to inject namespaces into a document in specific places -->
    <xsl:template match="/">
        <soap:Envelope>
            <soap:Header/>
            <soap:Body>
                <xsl:choose>
                    <!-- Handle 'Root' wrapper added by JSON to XML policy -->
                    <xsl:when test="normalize-space(/Root)">
                        <TestProcessMessage xmlns="http://tempuri.org/">
                            <xsl:apply-templates select="node()|@*"/>
                        </TestProcessMessage>
                    </xsl:when>
                    <!-- Handle 'Array' wrapper added by JSON to XML policy -->
                    <xsl:when test="normalize-space(/Array)">
                        <TestProcessMessage>
                            <xsl:apply-templates select="node()|@*"/>
                        </TestProcessMessage>
                    </xsl:when>
                    <!-- If the root element is not what was in the schema, add it -->
                    <xsl:when test="not(normalize-space(/TestProcessMessage))">
                        <TestProcessMessage>
                            <xsl:apply-templates select="node()|@*"/>
                        </TestProcessMessage>
                    </xsl:when>
                    <!-- everything checks out,  just copy the xml -->
                    <xsl:otherwise>
                        <xsl:apply-templates select="node()|@*"/>
                    </xsl:otherwise>
                </xsl:choose>
            </soap:Body>
        </soap:Envelope>
    </xsl:template>

    <xsl:template match="/Root/*" name="copy-root">
        <xsl:element name="{local-name()}">
            <xsl:copy-of select="namespace::*"/>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="/Array/*" name="copy-array">
        <xsl:element name="{local-name()}">
            <xsl:copy-of select="namespace::*"/>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="*[not(local-name()='Root') and not(local-name()='Array')]" name="copy-all">
        <xsl:element name="{local-name()}">
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="node()"/>
        </xsl:element>
    </xsl:template>

    <!-- template to copy the rest of the nodes -->
    <xsl:template match="comment() | processing-instruction()">
        <xsl:copy/>
    </xsl:template>
</xsl:stylesheet>

xmlns="" 被添加到子元素中,如下所示。

<soap:Envelope xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
               xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
               xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
               xmlns:tns="http://tempuri.org/">
   <soap:Header/>
   <soap:Body>
      <TestProcessMessage xmlns="http://tempuri.org/">
         <TargetApplication xmlns="">LoyaltyAdaptor</TargetApplication>
         <Chain xmlns="">1000</Chain>
         <Branch xmlns="">0</Branch>
         <InSessionKey xmlns="">0</InSessionKey>
         <MessageNumber xmlns="">0</MessageNumber>
         <Compression xmlns="">0</Compression>
         <TimeOut xmlns="">50000</TimeOut>
         <buffer xmlns="">xxx</buffer>
      </TestProcessMessage>
   </soap:Body>
</soap:Envelope>

要求是仅在元素“TestProcessMessage”上具有 xmlns 命名空间,如下所示。

<soap:Body>
      <TestProcessMessage xmlns="http://tempuri.org/">
         <TargetApplication xmlns="">LoyaltyAdaptor</TargetApplication>
         <Chain>1000</Chain>
         <Branch>0</Branch>
         <InSessionKey>0</InSessionKey>
         <MessageNumber>0</MessageNumber>
         <Compression>0</Compression>
         <TimeOut>50000</TimeOut>
         <buffer>xxx</buffer>
      </TestProcessMessage>
   </soap:Body>

更新: 添加用于此转换的原始 WSDL

<wsdl:definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://tempuri.org/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
<s:element name="Login">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Chain" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Branch" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Password" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="LoginResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="LoginResult" type="s:int"/>
<s:element minOccurs="0" maxOccurs="1" name="SessionKey" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="ProcessMessage">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="TargetApplication" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Chain" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Branch" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="inSessionKey" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="MessageNumber" type="s:int"/>
<s:element minOccurs="1" maxOccurs="1" name="Compression" type="s:int"/>
<s:element minOccurs="0" maxOccurs="1" name="buffer" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="TimeOut" type="s:long"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="ProcessMessageResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="ProcessMessageResult" type="s:int"/>
<s:element minOccurs="1" maxOccurs="1" name="ProcessingTime" type="s:long"/>
<s:element minOccurs="0" maxOccurs="1" name="SessionKey" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="ResponseBuffer" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="DropCounterCategory">
<s:complexType/>
</s:element>
<s:element name="DropCounterCategoryResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="DropCounterCategoryResult" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="TestProcessMessage">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="TargetApplication" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Chain" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Branch" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="inSessionKey" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="MessageNumber" type="s:int"/>
<s:element minOccurs="1" maxOccurs="1" name="Compression" type="s:int"/>
<s:element minOccurs="0" maxOccurs="1" name="buffer" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="TimeOut" type="s:long"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="TestProcessMessageResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="TestProcessMessageResult" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="Watchdog">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Chain" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Branch" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="WatchdogResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="WatchdogResult" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="ErrorCode" type="s:int"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="Ping">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="PingApplication" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="ApplicationToPing" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="PingResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="PingResult" type="s:boolean"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="Test">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Chain" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Branch" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="TestResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="TestResult" type="s:int"/>
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="LoginSoapIn">
<wsdl:part name="parameters" element="tns:Login"/>
</wsdl:message>
<wsdl:message name="LoginSoapOut">
<wsdl:part name="parameters" element="tns:LoginResponse"/>
</wsdl:message>
<wsdl:message name="ProcessMessageSoapIn">
<wsdl:part name="parameters" element="tns:ProcessMessage"/>
</wsdl:message>
<wsdl:message name="ProcessMessageSoapOut">
<wsdl:part name="parameters" element="tns:ProcessMessageResponse"/>
</wsdl:message>
<wsdl:message name="DropCounterCategorySoapIn">
<wsdl:part name="parameters" element="tns:DropCounterCategory"/>
</wsdl:message>
<wsdl:message name="DropCounterCategorySoapOut">
<wsdl:part name="parameters" element="tns:DropCounterCategoryResponse"/>
</wsdl:message>
<wsdl:message name="TestProcessMessageSoapIn">
<wsdl:part name="parameters" element="tns:TestProcessMessage"/>
</wsdl:message>
<wsdl:message name="TestProcessMessageSoapOut">
<wsdl:part name="parameters" element="tns:TestProcessMessageResponse"/>
</wsdl:message>
<wsdl:message name="WatchdogSoapIn">
<wsdl:part name="parameters" element="tns:Watchdog"/>
</wsdl:message>
<wsdl:message name="WatchdogSoapOut">
<wsdl:part name="parameters" element="tns:WatchdogResponse"/>
</wsdl:message>
<wsdl:message name="PingSoapIn">
<wsdl:part name="parameters" element="tns:Ping"/>
</wsdl:message>
<wsdl:message name="PingSoapOut">
<wsdl:part name="parameters" element="tns:PingResponse"/>
</wsdl:message>
<wsdl:message name="TestSoapIn">
<wsdl:part name="parameters" element="tns:Test"/>
</wsdl:message>
<wsdl:message name="TestSoapOut">
<wsdl:part name="parameters" element="tns:TestResponse"/>
</wsdl:message>
<wsdl:portType name="CommpointServiceSoap">
<wsdl:operation name="Login">
<wsdl:input message="tns:LoginSoapIn"/>
<wsdl:output message="tns:LoginSoapOut"/>
</wsdl:operation>
<wsdl:operation name="ProcessMessage">
<wsdl:input message="tns:ProcessMessageSoapIn"/>
<wsdl:output message="tns:ProcessMessageSoapOut"/>
</wsdl:operation>
<wsdl:operation name="DropCounterCategory">
<wsdl:input message="tns:DropCounterCategorySoapIn"/>
<wsdl:output message="tns:DropCounterCategorySoapOut"/>
</wsdl:operation>
<wsdl:operation name="TestProcessMessage">
<wsdl:input message="tns:TestProcessMessageSoapIn"/>
<wsdl:output message="tns:TestProcessMessageSoapOut"/>
</wsdl:operation>
<wsdl:operation name="Watchdog">
<wsdl:input message="tns:WatchdogSoapIn"/>
<wsdl:output message="tns:WatchdogSoapOut"/>
</wsdl:operation>
<wsdl:operation name="Ping">
<wsdl:input message="tns:PingSoapIn"/>
<wsdl:output message="tns:PingSoapOut"/>
</wsdl:operation>
<wsdl:operation name="Test">
<wsdl:input message="tns:TestSoapIn"/>
<wsdl:output message="tns:TestSoapOut"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="CommpointServiceSoap" type="tns:CommpointServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="Login">
<soap:operation soapAction="http://tempuri.org/Login" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="ProcessMessage">
<soap:operation soapAction="http://tempuri.org/ProcessMessage" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="DropCounterCategory">
<soap:operation soapAction="http://tempuri.org/DropCounterCategory" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="TestProcessMessage">
<soap:operation soapAction="http://tempuri.org/TestProcessMessage" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Watchdog">
<soap:operation soapAction="http://tempuri.org/Watchdog" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Ping">
<soap:operation soapAction="http://tempuri.org/Ping" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Test">
<soap:operation soapAction="http://tempuri.org/Test" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="CommpointServiceSoap12" type="tns:CommpointServiceSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="Login">
<soap12:operation soapAction="http://tempuri.org/Login" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="ProcessMessage">
<soap12:operation soapAction="http://tempuri.org/ProcessMessage" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="DropCounterCategory">
<soap12:operation soapAction="http://tempuri.org/DropCounterCategory" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="TestProcessMessage">
<soap12:operation soapAction="http://tempuri.org/TestProcessMessage" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Watchdog">
<soap12:operation soapAction="http://tempuri.org/Watchdog" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Ping">
<soap12:operation soapAction="http://tempuri.org/Ping" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="Test">
<soap12:operation soapAction="http://tempuri.org/Test" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="CommpointService">
<wsdl:port name="CommpointServiceSoap" binding="tns:CommpointServiceSoap">
<soap:address location="http://xxx.asmx"/>
</wsdl:port>
<wsdl:port name="CommpointServiceSoap12" binding="tns:CommpointServiceSoap12">
<soap12:address location="http://yyy.asmx"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

我尝试了各种选择,但都没有解决问题。您能否建议如何实现这一目标?

【问题讨论】:

    标签: xml xslt apigee


    【解决方案1】:

    您需要了解的第一件事是:如果您在正确的命名空间中创建元素,命名空间声明将自行处理。 xmlns="" 声明存在,因为您在错误的命名空间中创建了元素。具体来说,当您想要命名空间 http://tempuri.org/ 中的元素时,您创建了一个无命名空间元素。

    当您创建一个元素时,它不会自动进入与其父元素相同的命名空间。它位于您放入的任何命名空间中。如果它与其父元素的命名空间不同,则会输出命名空间声明以反映这种差异。

    现在,您实际上并没有向我们展示创建Chain 元素的代码(例如),但那是错误的代码。有三种创建元素的方法(文字结果元素、xsl:element 指令和xsl:copy),解决问题的方法将取决于您使用的是哪一种。

    【讨论】:

    • 谢谢,迈克尔。我在这里更新了 WSDL。要求是将 WSDL SOAP 转换为 JSON 格式,在转换过程中出现了这个问题。 WSDL 上有一个 SOAPAction,它将把命名空间添加到操作中,但我不确定如何在 XSLT 中使用它。我只需要在 WSDL 中提到的每个操作的根上获取 xmlns,但它甚至会出现在子元素中。 tempuri.org"> ...
    猜你喜欢
    • 1970-01-01
    • 2012-04-29
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多