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 Construct | Meaning | Example |
|---|---|---|
xsd:element | A named data field | <xsd:element name="city" type="xsd:string"/> |
xsd:complexType | A structured type with multiple fields | Like a class or interface |
xsd:sequence | Fields must appear in this order | Ordered list of elements |
xsd:string | Text value | "Tokyo" |
xsd:int | Integer value | 42 |
xsd:decimal | Decimal number | 23.5 |
xsd:date | ISO date | 2025-09-19 |
xsd:boolean | True/false | true |
minOccurs="0" | Field is optional | Can be omitted |
maxOccurs="unbounded" | Field is an array | Repeating 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:
| Attribute | Values | Meaning |
|---|---|---|
style | document or rpc | How the body is structured |
transport | http://schemas.xmlsoap.org/soap/http | HTTP transport |
use | literal or encoded | How types are serialized |
soapAction | URI string | Value 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"/>
| Aspect | SOAP 1.1 | SOAP 1.2 |
|---|---|---|
| Namespace | http://schemas.xmlsoap.org/soap/envelope/ | http://www.w3.org/2003/05/soap-envelope |
| Content-Type | text/xml; charset=utf-8 | application/soap+xml; charset=utf-8 |
| SOAPAction | HTTP header | action parameter in Content-Type |
| Fault codes | Client, Server | Sender, 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">
| Prefix | URI | Purpose |
|---|---|---|
wsdl | http://schemas.xmlsoap.org/wsdl/ | WSDL structure elements |
soap | http://schemas.xmlsoap.org/wsdl/soap/ | SOAP 1.1 binding extensions |
xsd | http://www.w3.org/2001/XMLSchema | XML 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:
- Start at
<wsdl:service>— Find the endpoint URL and port name - Follow the binding — Check the SOAP version, style, and SOAPAction values
- Read the portType — List all available operations and their input/output messages
- Trace messages to types — Understand what data each operation expects and returns
- 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
| Tool | Type | Best For |
|---|---|---|
| SoapUI | Desktop app | Full WSDL testing, request generation |
| Wizdler | Chrome extension | Quick operation browsing |
| curl | Command line | Raw SOAP request testing |
| Visual Studio | IDE | WCF client generation (.NET) |
| wsimport | CLI | Java 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.