Как я могу избежать передачи атрибута пространства имен xmlns дочерним элементам в XSLT? - PullRequest
0 голосов
/ 19 июня 2020

Я новичок ie с XSLT. Ниже приведен фрагмент кода моей таблицы стилей, и я добавил целевое пространство имен = "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>

Требуется наличие пространства имен xmlns только для элемента «TestProcessMessage», как показано ниже.

<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>

Я пробовал различные варианты, но ничего не решило проблему. Не могли бы вы посоветовать, как этого добиться?

1 Ответ

0 голосов
/ 19 июня 2020

Первое, что вам нужно понять: если вы создаете элементы в правильном пространстве имен, объявления пространства имен будут сами себя заботить. Объявление xmlns="" существует, потому что вы создали элемент в неправильном пространстве имен. В частности, вы создали элемент без пространства имен, когда вам нужен элемент в пространстве имен http://tempuri.org/.

Когда вы создаете элемент, он автоматически go не находится в том же пространстве имен, что и его родительский элемент. Он входит в любое пространство имен, в которое вы его поместили. Если оно отличается от пространства имен его родительского элемента, будет выведено объявление пространства имен, чтобы отразить это различие. создает элемент Chain (например), но это неправильный код. Существует три способа создания элементов (буквальные элементы результата, инструкция xsl:element и xsl:copy), и способ решения проблемы будет зависеть от того, какой из них вы используете.

...