Packages
erlcloud
0.9.2-rc.1
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_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;
{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:flatten([get_text(Node) || Node <- 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
"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.