ESC
Type to search...
S
Soli Docs

SOAP Class

Make SOAP calls and process XML data for web services.

SOAP.call(url, action, envelope, headers?)

SOAP.call(url, action, envelope, headers?)

Makes a SOAP request by performing an HTTP POST with the SOAP envelope. Returns the response Hash directly (auto-resolved).

Parameters

url : String - The SOAP service endpoint URL
action : String - The SOAP action/method name
envelope : String - The complete SOAP envelope XML
headers : Hash (optional) - Additional HTTP headers

Returns

Hash - Response with status, body (raw XML), and parsed (nested Hash)
# Build
let body = "<GetWeather xmlns=\"http://example.com/weather\"><City>London</City></GetWeather>"
let envelope = SOAP.wrap(body)

# Make the SOAP call (returns Hash directly, no await needed)
let result = SOAP.call(
    "https://weather.example.com/service",
    "http://example.com/weather/GetWeather",
    envelope
)

if result["status"] == 200 {
    let response = result["parsed"]["soap:Envelope"]["soap:Body"]["GetWeatherResponse"]
    let temp = response["Temperature"]
    let condition = response["Condition"]
    
    println("Temperature: " + temp)
    println("Condition: " + condition)
}

SOAP.wrap(body)

SOAP.wrap(body)

Wraps an XML body in a complete SOAP envelope with the standard SOAP 1.1 namespace.

Parameters

body : String - The XML body content

Returns

String - Complete SOAP envelope XML
let body = "<GetWeather xmlns=\"http://example.com/weather\"><City>London</City></GetWeather>"
let envelope = SOAP.wrap(body)
# Returns complete SOAP envelope with xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"

SOAP.parse(xml)

SOAP.parse(xml)

Parses an XML string into a nested Hash structure for easy access.

Parameters

xml : String - XML string to parse

Returns

Hash - Nested Hash with element names as keys
let xml = "<?xml version=\"1.0\"?><root><item>value</item></root>"
let parsed = SOAP.parse(xml)
# Returns: { "root" => { "item" => { "_text" => "value" } } }

SOAP.xml_escape(text)

SOAP.xml_escape(text)

Escapes special XML characters for safe inclusion in XML documents.

Parameters

text : String - The text to escape

Returns

String - XML-escaped text (<, >, &, ", ')
let escaped = SOAP.xml_escape("<script>alert('xss')</script>")
# Returns: "&lt;script&gt;alert(&apos;xss&ript)"

SOAP.to_xml(hash, root_element?)

SOAP.to_xml(hash, root_element?)

Converts a Hash (including nested hashes and arrays) to XML string. Supports attributes with @ prefix and text content with _text key.

Parameters

hash : Hash - The hash to convert to XML
root_element : String (optional) - Root element name (default: "root")

Returns

String - XML string

Special Keys

@name - Creates attribute on parent element
_text - Sets text content of element
let data = {
    "user" => {
        "@id" => "123",
        "name" => "John",
        "address" => {
            "street" => "123 Main St",
            "city" => "Boston"
        },
        "tags" => ["admin", "user"]
    }
}

let xml = SOAP.to_xml(data, "users")
# Returns XML:
# <users>
#   <user id="123">
#     <name>John</name>
#     <address>
#       <street>123 Main St</street>
#       <city>Boston</city>
#     </address>
#     <tags_0>admin</tags_0>
#     <tags_1>user</tags_1>
#   </user>
# </users>

With _text for Element Content

let data = {
    "product" => {
        "name" => "Laptop",
        "description" => {
            "_text" => "A high-performance laptop with 16GB RAM"
        },
        "price" => "999.99"
    }
}

let xml = SOAP.to_xml(data, "catalog")
# Returns:
# <catalog>
#   <product>
#     <name>Laptop</name>
#     <description>A high-performance laptop with 16GB RAM</description>
#     <price>999.99</price>
#   </product>
# </catalog>

Complete SOAP Example

# Build the SOAP request body
let body = "<GetWeather xmlns=\"http://example.com/weather\"><City>London</City></GetWeather>"
let envelope = SOAP.wrap(body)

# Make the SOAP call (auto-resolved, no await needed)
let result = SOAP.call(
    "https://weather.example.com/service",
    "http://example.com/weather/GetWeather",
    envelope,
    { "Authorization": "Bearer token123" }
)

# Handle the response
if result["status"] == 200 {
    let response = result["parsed"]["soap:Envelope"]["soap:Body"]["GetWeatherResponse"]
    let temp = response["Temperature"]
    let condition = response["Condition"]
    
    println("Temperature: " + temp)
    println("Condition: " + condition)
} else {
    println("Error: " + result["body"])
}

Response Structure

The SOAP.call() returns a Hash with the following structure:

{
  "status": 200,           # HTTP status code
  "status_text": "OK",      # HTTP status text
  "body": "<?xml ...>",  # Raw XML response string
  "headers": {...},         # Response headers Hash
  "parsed": {              # Parsed XML as nested Hash
    "soap:Envelope": {
      "soap:Body": {
        "ResponseElement": {
          "Field1": "value",
          "Field2": "value"
        }
      }
    }
  }
}