it-swarm.com.de

Was ist der Unterschied zwischen Typ und Element in WSDL?

In der WSDL-Datei kann eine Funktion einen Typ oder ein Element zurückgeben. Ich habe bisher nur benutzerdefinierte Typen als Ergebnisse verwendet. Ich frage mich jedoch, wann das Element geeigneter sein sollte als der Typ. Was ist der Unterschied zwischen ihnen?

Gibt es einen Unterschied zwischen

<wsdl:message name="MyFunction">
    <wsdl:part name="parameters" element="tns:Person"></wsdl:part>
</wsdl:message>

und

<wsdl:message name="MyFunction">
    <wsdl:part name="parameters" type="tns:Person"></wsdl:part>
</wsdl:message>

aus Sicht des Kunden (Anwendung, die den Webdienst verwendet)?

Die obige Frage führt, wie Skaffman wies, zu einer weiteren Frage. Was ist der Unterschied zwischen

<xs:element name="Person" ... >
 ...
</xs:element>

und

<xs:complexType name="Person">
   ...
</xs:complexType>

?

42
czuk

Es ist mehr als das.

Es gibt einige Unklarheiten in den Standards, die Interoperabilitätsprobleme verursachen können. Typ oder Element müssen abhängig davon verwendet werden, ob Sie einen dokumentbasierten Dienst oder einen RPC-basierten Dienst verwenden.

Es gibt auch Unklarheiten. Wenn du sagst

<wsdl:message name="message1" type="ns:type1"/>

Dann haben Sie gesagt, dass der Inhalt der Nachricht anhand des Typs "ns: type1" überprüft werden muss. Sie haben jedoch nichts zu dem Element gesagt, das den Inhalt enthält. In welchem ​​Namensraum wird es sein?

Weitere Informationen hierzu finden Sie im WS-I Basic Profile .


In den Kommentaren zu "document/literal" vs. "document/literal/wrapped" gab es einige Diskussionen. Hier ist mein Take.

Ich habe gerade einen Webservice erstellt. Hier ist die ganze Sache:

using System.Web.Services;

namespace WebService1
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    public class SimpleMathService : WebService
    {
        [WebMethod]
        public int Add(int a, int b)
        {
            return a + b;
        }

        [WebMethod]
        public int Multiply(int a, int b)
        {
            return a*b;
        }
    }
}

Ich werde nicht die komplette WSDL posten, aber hier sind die "guten Teile":

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" 
    xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
     targetNamespace="http://tempuri.org/" xmlns:tns="http://tempuri.org/" >
    <wsdl:types>
        <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
            <s:element name="Add">
                <s:complexType>
                    <s:sequence>
                        <s:element minOccurs="1" maxOccurs="1" name="a" type="s:int"/>
                        <s:element minOccurs="1" maxOccurs="1" name="b" type="s:int"/>
                    </s:sequence>
                </s:complexType>
            </s:element>
            <s:element name="AddResponse">
                <s:complexType>
                    <s:sequence>
                        <s:element minOccurs="1" maxOccurs="1" 
                           name="AddResult" type="s:int"/>
                    </s:sequence>
                </s:complexType>
            </s:element>
            <s:element name="int" type="s:int"/>
        </s:schema>
    </wsdl:types>
    <wsdl:message name="AddSoapIn">
        <wsdl:part name="parameters" element="tns:Add"/>
    </wsdl:message>
    <wsdl:message name="AddSoapOut">
        <wsdl:part name="parameters" element="tns:AddResponse"/>
    </wsdl:message>
    <wsdl:portType name="SimpleMathServiceSoap">
        <wsdl:operation name="Add">
            <wsdl:input message="tns:AddSoapIn"/>
            <wsdl:output message="tns:AddSoapOut"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="SimpleMathServiceSoap" type="tns:SimpleMathServiceSoap">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="Add">
            <soap:operation soapAction="http://tempuri.org/Add" style="document"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="SimpleMathService">
        <wsdl:port name="SimpleMathServiceSoap" binding="tns:SimpleMathServiceSoap">
            <soap:address location="http://localhost:5305/SimpleMathService.asmx"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

Beachten Sie, wie das Word "Wrapped" nicht angezeigt wird. Was IBM in seinem Dokument "document/literal/wrapped" aufruft, ist einfach "document/literal", das verwendet wird, um einen einzelnen Nachrichtenteil zu verwenden, der einen Namen hat, der vom Namen des Dienstes abgeleitet ist, und sich darauf bezieht zu einem Element, und die beide Parameter für die Operation enthalten.

Hier gibt es nichts Magisches, nichts Unübliches. 

In vielen Standardisierungsorganisationen treten Unternehmen auf, um Partei zu ergreifen. Im Falle von SOAP haben wir die "RPC-Seite" und die "Dokumentenseite". RPC ist vielen Leuten eher vertraut - es bildet eins zu eins mit einem Funktionsaufruf ab. Das Dokument ist weniger vertraut und erfordert, dass Sie in Bezug auf einfaches XML denken. Vielleicht war IBM auf der RPC-Seite, ich weiß es nicht.


Ich habe jetzt das IBM Dokument "Welcher Stil von WSDL" fertiggestellt. Die Zusammenfassung ist:

Zusammenfassung

Es gibt vier Bindungsstile (es gibt wirklich fünf, aber das Dokument/die Kodierung ist bedeutungslos). Während jeder Stil seinen Platz hat, ist der beste Stil in den meisten Situationen der Umbruch von Dokumenten/Wörtern.


Ich möchte auch auf die Stellen im Dokument reagieren, an denen der Schwierigkeitsgrad beim Disponieren erläutert wird, je nachdem, ob der Operationsname in der Nachricht vorhanden ist. Dies ist kein Problem. Wenn Sie das Dokument lesen, werden Sie feststellen, dass im Abschnitt <binding> nie etwas besprochen wird. Die Lösung für das Problem "Kein Operationsname" ist vorhanden.

<wsdl:binding name="SimpleMathServiceSoap" type="tns:SimpleMathServiceSoap">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="Add">
        <soap:operation soapAction="http://tempuri.org/Add" style="document"/>

Die soapAction wird in den HTTP-Headern der Anforderung gesendet und kann zum Absenden verwendet werden:

POST /SimpleMathService.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/Add"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
       xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <Add xmlns="http://tempuri.org/">
      <a>int</a>
      <b>int</b>
    </Add>
  </soap:Body>
</soap:Envelope>
16
John Saunders

Welches Sie verwenden, hängt von dem Schema ab, auf das es verweist. Wenn tns: Person ist im Schema definiert als:

<xs:element name="Person" ... >
 ...
</xs:element>

Dann benutzt du 

<wsdl:part name="parameters" element="tns:Person">

Wenn dagegen das Schema definiert ist als 

<xs:complexType name="Person">
   ...
</xs:complexType>

dann verwendest du 

<wsdl:part name="parameters" type="tns:Person">

Die Frage ist also, was der Unterschied zwischen Schemaelementen und Schematypen ist. 

10
skaffman

Ich kann den WSDL-Teil der Frage nicht kommentieren, aber ich werde den XML-Schema-Teil beantworten.

<xs:complexType> definiert einen Typ, der content eines Elements beschreibt, ohne das Element selbst zu beschreiben (d. h. seinen Namen). <xs:element> beschreibt ein Element (insbesondere seinen Namen), nicht jedoch seinen Typ. <xs:element> always reference der Typ für den Inhalt des von ihm beschriebenen Elements. Dies kann ein Verweis auf einen vorhandenen Typ sein (einschließlich, aber nicht beschränkt auf <xs:complexType> - dies kann beispielsweise auch <xs:simpleType> sein) an anderer Stelle im Schema oder eine Inline-<xs:complexType>-Definition

<xs:element name="foo">
   <xs:complexType>
      ...
   </xs:complexType>
</xs:element>

Da das obige Konstrukt so üblich ist, können Sie <xs:complexType> tatsächlich ganz weglassen, und es wird impliziert. 

Ob Sie Typen immer separat definieren und dann in Elementdeklarationen referenzieren oder ob Sie Elementtypen lieber in Elementdeklarationen definieren möchten, ist eine Frage des Stils. 

2
Pavel Minaev
<xs:element name="person" type="persontype"/>

<xs:complexType name="persontype">
  <xs:sequence>
    <xs:element name="firstname" type="xs:string"/>
    <xs:element name="lastname" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

das <element> des type-Attributs verweist auf <complexType> des name-Attributs.


<wsdl:message name="MyFunction">
    <wsdl:part name="parameters" element="tns:person"></wsdl:part>
</wsdl:message>

und

<wsdl:message name="MyFunction">
    <wsdl:part name="parameters" type="tns:person"></wsdl:part>
</wsdl:message>
  • Der <part>-Parameter ist einem konkreten Typ zugeordnet, der im <types>-Containerelement definiert ist. und <part> kann entweder durch type-Attribut auf <complexType> oder auf <element> durch Elementattribut verweisen, wie oben gezeigt.
  • Es kann entweder <complexType> oder <portType> oder ein beliebiger sein, auf den das type-Attribut verweist.
0
Premraj