What is the difference between Type and Element in WSDL?

There's more to it than that.

There is some ambiguity in the standards that can cause interoperability problems. You have to use type or element depending on whether you're using a Document-based service or an RPC-based service.

There are also ambiguities. If you say

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

Then you've said that the content of the message must validate against type "ns:type1". But you've said nothing about the element that contains the content. What namespace will it be in?

Refer to the WS-I Basic Profile for some rules on this.


There's been some discussion in the comments about "document/literal" vs. "document/literal/wrapped". Here's my take.

I just created a web service. Here's the whole thing:

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

I won't post the entire WSDL, but here are the "good parts":

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

Note how the word "wrapped" does not appear. What IBM in their document is calling "document/literal/wrapped" is simply "document/literal", that happens to use a single message part, that happens to have a name derived from the name of the service, and that happens to refer to an element, and which happens to contain both the parameters to the operation.

There's nothing magical here, there's nothing non standard here.

In many standards organizations companies wind up taking sides. In the case of SOAP, we've got the "RPC side" and the "Document side". RPC is more familiar to many people - it maps one to one with a function call. Document is less familiar, and requires that you actually think in terms of simple XML. Perhaps IBM was on the RPC side, I don't know.


I have now finished the IBM document, Which style of WSDL. The summary is:

Summary

There are four binding styles (there are really five, but document/encoded is meaningless). While each style has its place, under most situations the best style is document/literal wrapped.


I also want to react to the places in the document where it discusses the level of difficulty in dispatching, based on whether the operation name is present in the message. This is a non-issue. If you read the document, you'll note that it never discusses anything in the <binding> section. The solution to the "no operation name" problem is there.

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

The soapAction is sent in the HTTP headers of the request, and can be used for dispatching:

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>

Which one you use depends on the schema to which it is referring. If tns:Person is defined in the schema as:

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

Then you use

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

If, on the other hand, the schema is defined as

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

then you use

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

So the question is really what's the difference between Schema elements, and Schema types.


I cannot comment on the WSDL part of the question, but I'll answer the XML Schema part.

<xs:complexType> defines a type, which describes content of an element, without describing the element itself (i.e. its name). <xs:element> describes an element (specifically its name), but not its type. However, <xs:element> always references the type for the content of the element it describes. This can be a reference to an existing type (including, but not limited to, <xs:complexType> - it can also be <xs:simpleType>, for example) definition elsewhere in the schema, or an inline <xs:complexType> definition:

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

Since the above construct is so common, you can actually omit <xs:complexType> entirely, and it will be implied.

As for whether you should always define types separately and then reference them in element declarations, or whether you should prefer defining element types inline within element declarations, it is a matter of style.