ErlangでSOAPをデコードしてみる

#!/opt/local/bin/escript

-include_lib("xmerl/include/xmerl.hrl").

main(_) -> 
        XmlData = "<soapenv:Envelope " ++
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " ++
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " ++
"xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " ++
"xmlns:cwmp=\"urn:dslforum-org:cwmp-1-0\">" ++
"<soapenv:Header>" ++
"<cwmp:ID soap-env:mustUnderstand=\"1\">999</cwmp:ID>" ++
"<cwmp:HoldRequest soap-env:mustUnderstand=\"1\">0</cwmp:HoldRequest>" ++
"</soapenv:Header>" ++
"<soapenv:Body>" ++
"</soapenv:Body>" ++
"</soapenv:Envelope>",

        {Header, Body} = unmarshall(XmlData),
        io:format("SoapHeader: ~p~n", [Header]),
        io:format("SoapBody: ~p~n", [Body]).

unmarshall(Xml) ->
        {SoapEnv, _Rest} = xmerl_scan:string(Xml),
        [SoapHead, SoapBody] = SoapEnv#xmlElement.content,
        {
        [soap_header(C) || C <- SoapHead#xmlElement.content],
        [soap_body(C) || C <- SoapBody#xmlElement.content]
        }.

soap_header(C) ->
        Name = C#xmlElement.name,
        [Value] = [Content#xmlText.value || 
                Content <- C#xmlElement.content],
        Attr = [{A#xmlAttribute.name, A#xmlAttribute.value} || 
                A <- C#xmlElement.attributes],
        {Name, Value, Attr}.

soap_body(C) ->
        {
        C#xmlElement.name,
        C#xmlElement.content,
        C#xmlElement.attributes
        }.