wsdlsoaptutorialweb-services

How to Read and Understand WSDL Files: A Developer's Visual Guide

SOAPless Team8 min read

WSDL files are the blueprints of SOAP services. They define everything a client needs to know to communicate with the service — what operations are available, what data to send, what data comes back, and where to send requests.

The problem is that WSDLs are notoriously hard to read. A single WSDL can span hundreds of lines of XML with deeply nested schemas, multiple namespaces, and cross-references between elements. Most developers either ignore the WSDL entirely (and rely on generated code) or spend hours staring at XML, trying to piece together how the service works.

This guide teaches you to read WSDLs systematically. Once you understand the five core elements and how they connect, any WSDL becomes navigable.

The Five Core Elements of WSDL 1.1

Every WSDL 1.1 document is built from five elements, connected in a specific order:

┌─────────────────────────────────────────────┐
│  <wsdl:definitions>                         │
│                                             │
│  ┌─────────┐                                │
│  │  types  │  XSD schemas — data structures │
│  └────┬────┘                                │
│       ↓                                     │
│  ┌─────────┐                                │
│  │ message │  Named groups of typed parts   │
│  └────┬────┘                                │
│       ↓                                     │
│  ┌──────────┐                               │
│  │ portType │  Abstract operations          │
│  └────┬─────┘                               │
│       ↓                                     │
│  ┌─────────┐                                │
│  │ binding │  Concrete protocol details     │
│  └────┬────┘                                │
│       ↓                                     │
│  ┌─────────┐                                │
│  │ service │  Network address (endpoint)    │
│  └─────────┘                                │
│                                             │
└─────────────────────────────────────────────┘

Think of it as a stack: each layer depends on the one above it. The service tells you where to call. The binding tells you how to call. The portType tells you what to call. The message tells you what data to send. The types define the shape of that data.

A Complete WSDL Example

Let us walk through a realistic WSDL for a weather service with two operations: GetCurrentWeather and GetForecast.

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:tns="http://example.com/weatherservice"
  targetNamespace="http://example.com/weatherservice"
  name="WeatherService">

  <!-- ==================== -->
  <!-- 1. TYPES             -->
  <!-- ==================== -->
  <wsdl:types>
    <xsd:schema targetNamespace="http://example.com/weatherservice">

      <xsd:element name="GetCurrentWeather">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="city" type="xsd:string"/>
            <xsd:element name="countryCode" type="xsd:string" minOccurs="0"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>

      <xsd:element name="GetCurrentWeatherResponse">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="temperature" type="xsd:decimal"/>
            <xsd:element name="unit" type="xsd:string"/>
            <xsd:element name="condition" type="xsd:string"/>
            <xsd:element name="humidity" type="xsd:int"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>

      <xsd:element name="GetForecast">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="city" type="xsd:string"/>
            <xsd:element name="days" type="xsd:int"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>

      <xsd:element name="GetForecastResponse">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="forecasts" type="tns:ForecastDay"
                         maxOccurs="unbounded"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>

      <xsd:complexType name="ForecastDay">
        <xsd:sequence>
          <xsd:element name="date" type="xsd:date"/>
          <xsd:element name="high" type="xsd:decimal"/>
          <xsd:element name="low" type="xsd:decimal"/>
          <xsd:element name="condition" type="xsd:string"/>
        </xsd:sequence>
      </xsd:complexType>

    </xsd:schema>
  </wsdl:types>

  <!-- ==================== -->
  <!-- 2. MESSAGES           -->
  <!-- ==================== -->
  <wsdl:message name="GetCurrentWeatherRequest">
    <wsdl:part name="parameters" element="tns:GetCurrentWeather"/>
  </wsdl:message>

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

  <wsdl:message name="GetForecastRequest">
    <wsdl:part name="parameters" element="tns:GetForecast"/>
  </wsdl:message>

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

  <!-- ==================== -->
  <!-- 3. PORT TYPE          -->
  <!-- ==================== -->
  <wsdl:portType name="WeatherServicePortType">
    <wsdl:operation name="GetCurrentWeather">
      <wsdl:input message="tns:GetCurrentWeatherRequest"/>
      <wsdl:output message="tns:GetCurrentWeatherResponse"/>
    </wsdl:operation>
    <wsdl:operation name="GetForecast">
      <wsdl:input message="tns:GetForecastRequest"/>
      <wsdl:output message="tns:GetForecastResponse"/>
    </wsdl:operation>
  </wsdl:portType>

  <!-- ==================== -->
  <!-- 4. BINDING            -->
  <!-- ==================== -->
  <wsdl:binding name="WeatherServiceSoapBinding"
                type="tns:WeatherServicePortType">
    <soap:binding style="document"
                  transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="GetCurrentWeather">
      <soap:operation
        soapAction="http://example.com/weatherservice/GetCurrentWeather"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="GetForecast">
      <soap:operation
        soapAction="http://example.com/weatherservice/GetForecast"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>

  <!-- ==================== -->
  <!-- 5. SERVICE            -->
  <!-- ==================== -->
  <wsdl:service name="WeatherService">
    <wsdl:port name="WeatherServicePort"
               binding="tns:WeatherServiceSoapBinding">
      <soap:address location="https://weather.example.com/soap"/>
    </wsdl:port>
  </wsdl:service>

</wsdl:definitions>

Now let us examine each section in detail.

1. Types: The Data Dictionary

The <wsdl:types> section contains XSD (XML Schema Definition) schemas that define the structure of all data used by the service. This is equivalent to TypeScript interfaces or JSON Schema definitions.

Key XSD concepts to understand:

XSD ConstructMeaningExample
xsd:elementA named data field<xsd:element name="city" type="xsd:string"/>
xsd:complexTypeA structured type with multiple fieldsLike a class or interface
xsd:sequenceFields must appear in this orderOrdered list of elements
xsd:stringText value"Tokyo"
xsd:intInteger value42
xsd:decimalDecimal number23.5
xsd:dateISO date2025-09-19
xsd:booleanTrue/falsetrue
minOccurs="0"Field is optionalCan be omitted
maxOccurs="unbounded"Field is an arrayRepeating element

Reading the GetCurrentWeather element tells us: "This operation accepts a required city (string) and an optional countryCode (string)."

Reading the ForecastDay complex type tells us: "Each forecast day contains a date, high temperature, low temperature, and condition — all in that order."

2. Messages: Named Parameter Groups

The <wsdl:message> elements group typed parts into named units. Each message references an element defined in the types section.

<wsdl:message name="GetCurrentWeatherRequest">
  <wsdl:part name="parameters" element="tns:GetCurrentWeather"/>
</wsdl:message>

This says: "The request message for GetCurrentWeather uses the GetCurrentWeather element as its parameters."

In document/literal style (the most common), each message typically has a single part pointing to an element. In RPC/encoded style (older, less common), messages may have multiple parts with explicit types.

3. PortType: The Interface Contract

The <wsdl:portType> defines abstract operations — essentially the API's method signatures. This is the most important section for understanding what the service can do.

<wsdl:portType name="WeatherServicePortType">
  <wsdl:operation name="GetCurrentWeather">
    <wsdl:input message="tns:GetCurrentWeatherRequest"/>
    <wsdl:output message="tns:GetCurrentWeatherResponse"/>
  </wsdl:operation>
</wsdl:portType>

Reading this: "The WeatherServicePortType interface has an operation called GetCurrentWeather that takes a GetCurrentWeatherRequest message and returns a GetCurrentWeatherResponse message."

Operations can also have <wsdl:fault> elements defining error responses.

4. Binding: Protocol Details

The <wsdl:binding> specifies how the abstract operations map to a concrete protocol. For SOAP services, this defines the SOAP version, encoding style, transport protocol, and SOAPAction headers.

<wsdl:binding name="WeatherServiceSoapBinding"
              type="tns:WeatherServicePortType">
  <soap:binding style="document"
                transport="http://schemas.xmlsoap.org/soap/http"/>

Key binding attributes:

AttributeValuesMeaning
styledocument or rpcHow the body is structured
transporthttp://schemas.xmlsoap.org/soap/httpHTTP transport
useliteral or encodedHow types are serialized
soapActionURI stringValue for the SOAPAction HTTP header

The most common combination is document/literal — the body contains an XML document matching the schema exactly. Older services may use rpc/encoded, which wraps parameters differently.

5. Service: The Endpoint Address

The <wsdl:service> element ties everything together by specifying where the service lives:

<wsdl:service name="WeatherService">
  <wsdl:port name="WeatherServicePort"
             binding="tns:WeatherServiceSoapBinding">
    <soap:address location="https://weather.example.com/soap"/>
  </wsdl:port>
</wsdl:service>

The soap:address location is the URL you will send HTTP requests to. A service can have multiple ports (for example, one for SOAP 1.1 and another for SOAP 1.2).

SOAP 1.1 vs 1.2 Binding Differences

If a WSDL supports SOAP 1.2, the binding section uses a different namespace:

<!-- SOAP 1.1 -->
<soap:binding xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
              style="document"
              transport="http://schemas.xmlsoap.org/soap/http"/>

<!-- SOAP 1.2 -->
<soap12:binding xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
                style="document"
                transport="http://schemas.xmlsoap.org/soap/http"/>
AspectSOAP 1.1SOAP 1.2
Namespacehttp://schemas.xmlsoap.org/soap/envelope/http://www.w3.org/2003/05/soap-envelope
Content-Typetext/xml; charset=utf-8application/soap+xml; charset=utf-8
SOAPActionHTTP headeraction parameter in Content-Type
Fault codesClient, ServerSender, Receiver

Understanding Namespaces

Namespaces are the most confusing part of WSDLs for developers coming from JSON-based APIs. Here is a quick reference for the namespaces you will encounter:

<wsdl:definitions
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:tns="http://example.com/weatherservice"
  targetNamespace="http://example.com/weatherservice">
PrefixURIPurpose
wsdlhttp://schemas.xmlsoap.org/wsdl/WSDL structure elements
soaphttp://schemas.xmlsoap.org/wsdl/soap/SOAP 1.1 binding extensions
xsdhttp://www.w3.org/2001/XMLSchemaXML Schema types
tns(varies per service)"This namespace" — the service's own namespace

The targetNamespace is the service's unique identifier. When you see tns:GetCurrentWeather, it refers to the GetCurrentWeather element in the target namespace.

Reading Strategy: Bottom-Up

When you open a WSDL for the first time, read it bottom-up:

  1. Start at <wsdl:service> — Find the endpoint URL and port name
  2. Follow the binding — Check the SOAP version, style, and SOAPAction values
  3. Read the portType — List all available operations and their input/output messages
  4. Trace messages to types — Understand what data each operation expects and returns
  5. Study the XSD types — Map out the complete data model

This bottom-up approach is faster because you start with concrete information (where to send requests) and work up to abstract details (data schemas).

Useful Tools for Exploring WSDLs

ToolTypeBest For
SoapUIDesktop appFull WSDL testing, request generation
WizdlerChrome extensionQuick operation browsing
curlCommand lineRaw SOAP request testing
Visual StudioIDEWCF client generation (.NET)
wsimportCLIJava client generation

SoapUI is particularly helpful because it parses the WSDL and generates sample requests for every operation, giving you a runnable starting point.

How SOAPless Helps

Reading WSDLs is a skill, but you should not have to exercise it every time you integrate with a SOAP service. SOAPless parses WSDLs automatically — paste the WSDL URL, and the platform extracts all operations, data types, and bindings without manual XML inspection.

Each operation becomes a REST endpoint with an auto-generated OpenAPI 3.0 specification. Instead of tracing messages to types and constructing XML envelopes by hand, you send JSON and receive JSON. The dashboard lets you test operations interactively, so you can explore a SOAP service's capabilities without writing any code or reading a single line of WSDL.

For teams that need to integrate multiple SOAP services, this eliminates the repeated cycle of WSDL parsing, envelope construction, and namespace debugging.