Packages
erlcloud
3.2.17
3.8.3
3.8.2
3.8.1
3.7.6
3.7.4
3.7.3
3.7.2
3.7.1
3.7.0
3.6.8
3.6.7
3.6.5
3.6.4
3.6.3
3.6.2
3.6.1
3.6.0
3.5.16
3.5.15
3.5.14
3.5.13
3.5.12
3.5.11
3.5.10
3.5.9
3.5.8
3.5.7
3.5.6
3.5.5
3.5.4
3.5.3
3.5.2
3.5.1
3.5.0
3.4.5
3.4.3
3.4.1
3.4.0
3.3.9
3.3.8
3.3.7
3.3.6
3.3.5
3.3.4
3.3.3
3.3.2
3.3.1
3.3.0
3.2.18
3.2.17
3.2.16
3.2.15
3.2.14
3.2.13
3.2.12
3.2.11
3.2.10
3.2.7
3.2.6
3.2.5
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
3.1.17
3.1.16
3.1.14
3.1.13
3.1.12
3.1.11
3.1.9
3.1.8
3.1.7
3.1.6
3.1.5
3.1.4
3.1.3
3.1.2
3.1.1
3.1.0
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
2.2.16
2.2.15
2.2.14
2.2.13
2.2.12
2.2.11
2.2.10
2.2.9
2.2.8
2.2.7
2.2.6
2.2.5
2.2.4
2.2.2
2.2.1
2.2.0
2.1.0
2.0.5
2.0.4
2.0.3
2.0.0
0.13.10
0.13.9
0.13.8
0.13.6
0.13.5
0.13.4
0.13.3
0.13.2
0.13.0
0.12.0
0.11.0
0.9.2
0.9.2-rc.1
0.9.1
0.9.0
AWS APIs library for Erlang
Current section
Files
Jump to
Current section
Files
src/erlcloud_xml.erl
-module(erlcloud_xml).
-export([decode/2, decode/3, get_bool/2, get_float/2, get_integer/2,
get_integer/3, get_list/2, get_text/1, get_text/2,
get_text/3, get_time/2]).
-include_lib("xmerl/include/xmerl.hrl").
decode(Values, Node) ->
lists:reverse(
lists:foldl(
fun ({Name, XPath, Type}, Output) ->
case get_value(XPath, Type, Node) of
undefined -> Output;
Value ->
[{Name, Value}|Output]
end
end, [], Values)
).
decode(Values, Node, Record) ->
lists:foldl(
fun ({Index, XPath, Type}, Output) ->
case get_value(XPath, Type, Node) of
undefined -> Output;
Value -> setelement(Index, Output, Value)
end
end, Record, Values
).
get_value(XPath, Type, Node) ->
case Type of
text -> get_text(XPath, Node);
optional_text -> get_text(XPath, Node, undefined);
integer -> get_integer(XPath, Node);
optional_integer ->
case get_text(XPath, Node, undefined) of
undefined -> undefined;
Text -> list_to_integer(Text)
end;
float -> get_float(XPath, Node);
time -> get_time(XPath, Node);
list -> get_list(XPath, Node);
boolean -> get_bool(XPath, Node);
optional_boolean ->
case get_text(XPath, Node, undefined) of
undefined -> undefined;
"true" -> true;
_ -> false
end;
present -> xmerl_xpath:string(XPath, Node) =/= [];
xml -> Node;
Fun when is_function(Fun, 1) ->
Fun(xmerl_xpath:string(XPath, Node));
{single, Fun} when is_function(Fun, 1) ->
case xmerl_xpath:string(XPath, Node) of
[] -> undefined;
[SubNode] -> Fun(SubNode)
end;
{map, Fun} when is_function(Fun, 1) ->
lists:map(Fun, xmerl_xpath:string(XPath, Node));
{optional_map, Fun} when is_function(Fun, 1) ->
case xmerl_xpath:string(XPath, Node) of
[] -> undefined;
List -> lists:map(Fun, List)
end;
{single, List} when is_list(List) ->
case xmerl_xpath:string(XPath, Node) of
[] -> undefined;
[SubNode] -> decode(List, SubNode)
end;
{value, Fun} when is_function(Fun, 1) ->
Fun(get_text(XPath, Node));
List when is_list(List) ->
[decode(List, SubNode) || SubNode <- xmerl_xpath:string(XPath, Node)]
end.
get_float(XPath, Node) ->
list_to_float(get_text(XPath, Node)).
get_text(#xmlText{value=Value}) -> Value;
get_text(#xmlElement{content=Content}) ->
lists:flatmap(fun get_text/1, Content).
get_text(XPath, Doc) -> get_text(XPath, Doc, "").
get_text({XPath, AttrName}, Doc, Default) ->
case xmerl_xpath:string(XPath ++ "/@" ++ AttrName, Doc) of
[] -> Default;
[#xmlAttribute{value=Value}|_] -> Value
end;
get_text(XPath, Doc, Default) ->
case xmerl_xpath:string(XPath ++ "/text()", Doc) of
[] -> Default;
TextNodes ->
lists:flatten([Node#xmlText.value || Node <- TextNodes])
end.
get_list(XPath, Doc) ->
[get_text(Node) || Node <- xmerl_xpath:string(XPath, Doc)].
get_integer(XPath, Doc) -> get_integer(XPath, Doc, 0).
get_integer(XPath, Doc, Default) ->
case get_text(XPath, Doc) of
"" -> Default;
Text -> list_to_integer(Text)
end.
get_bool(XPath, Doc) ->
case get_text(XPath, Doc, "false") of
"1" -> true;
"true" -> true;
_ -> false
end.
get_time(XPath, Doc) ->
case get_text(XPath, Doc, undefined) of
undefined -> undefined;
Time -> parse_time(Time)
end.
parse_time(String) ->
case re:run(String, "^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.\\d+)?Z", [{capture, all_but_first, list}]) of
{match, [Yr, Mo, Da, H, M, S]} ->
{{list_to_integer(Yr), list_to_integer(Mo), list_to_integer(Da)},
{list_to_integer(H), list_to_integer(M), list_to_integer(S)}};
nomatch ->
error
end.