defmodule Soap.Type do
@moduledoc """
Provides functions for parsing types to struct
"""
import SweetXml, except: [parse: 1]
@spec get_complex_types(String.t(), String.t()) :: map()
def get_complex_types(wsdl, x_path) do
wsdl
|> xpath(~x"#{x_path}"l)
|> Enum.reduce(%{}, &parse_types/2)
end
@spec parse_types(map(), map()) :: map()
defp parse_types(type_node, complex_type_acc) do
types_map =
type_node
|> xpath(~x"./xsd:sequence/xsd:element"l)
|> Enum.reduce(%{}, &parse_type_attributes/2)
Map.put(complex_type_acc, type_node |> xpath(~x"./@name"s) |> String.downcase(), types_map)
end
@spec parse_type_attributes(map(), map()) :: map()
defp parse_type_attributes(inner_node, element_acc) do
result_map =
[:nillable, :minOccurs, :maxOccurs]
|> Enum.reduce(%{type: inner_node |> xpath(~x"./@type"s)}, fn attr, init_map_acc ->
attr_val = inner_node |> xpath(~x"./@#{attr}"s)
case attr_val do
"" -> init_map_acc
_ -> Map.put(init_map_acc, attr, attr_val)
end
end)
Map.put(element_acc, inner_node |> xpath(~x"./@name"s), result_map)
end
end