1
1
% %%-------------------------------------------------------------------
2
- % %% @copyright (C) 2011-2021 , Erlang Solutions Ltd.
2
+ % %% @copyright (C) 2011-2024 , Erlang Solutions Ltd.
3
3
% %% @doc
4
4
% %% @end
5
5
% %% Created : 12 Jul 2011 by Michal Ptaszek <michal.ptaszek@erlang-solutions.com>
31
31
-type item () :: element () | attr () | cdata () | exml_stream :start () | exml_stream :stop ().
32
32
-type prettify () :: pretty | not_pretty .
33
33
34
+ % % @doc Calculate the length of the original XML payload
34
35
-spec xml_size (item () | [item ()]) -> non_neg_integer ().
35
36
xml_size ([]) ->
36
37
0 ;
@@ -54,14 +55,15 @@ xml_size({Key, Value}) ->
54
55
+ 4 % ="" and whitespace before
55
56
+ byte_size (Value ).
56
57
57
- % % @doc Sort a ( list of) `xmlel ()'.
58
+ % % @doc Sort in ascending order a list of xml `t:item ()'.
58
59
% %
59
60
% % Sorting is defined as calling `lists:sort/1' at:
60
- % % * all the `xmlel's provided (if there is a list of them) AND
61
- % % * all the `xmlel' elements' attributes recursively (the root and descendants) AND
62
- % % * all the `xmlel' children recursively (the root and descendants).
63
- % % The order is ascending.
64
- % %
61
+ % % <ul>
62
+ % % <li>all the `xmlel's provided (if there is a list of them) AND</li>
63
+ % % <li>all the `xmlel' elements' attributes recursively (the root and descendants) AND</li>
64
+ % % <li>all the `xmlel' children recursively (the root and descendants).</li>
65
+ % % </ul>
66
+ % % @end
65
67
% % The implementation of this function is a subtle modification of
66
68
% % https://github.com/erszcz/rxml/commit/e8483408663f0bc2af7896e786c1cdea2e86e43d
67
69
-spec xml_sort (item () | [item ()]) -> item () | [item ()].
@@ -99,31 +101,19 @@ to_iolist(Element) ->
99
101
to_pretty_iolist (Element ) ->
100
102
to_iolist (Element , pretty ).
101
103
104
+ % % @doc Parses a binary or a list of binaries into an XML `t:element()'.
102
105
-spec parse (binary () | [binary ()]) -> {ok , exml :element ()} | {error , any ()}.
103
106
parse (XML ) ->
104
107
exml_nif :parse (XML ).
105
108
106
- % % @doc Turn a –list of– exml element into iodata for IO interactions.
109
+ % % @doc Turn a –list of– exml elements into iodata for IO interactions.
107
110
% %
108
111
% % The `Pretty' argument indicates if the generated XML should have new lines and indentation,
109
112
% % which is useful for the debugging eye, or should rather be a minified version,
110
- % % which is better for IO.
111
- -spec to_iolist (exml_stream :element () | [exml_stream :element ()], prettify ()) -> iodata ().
113
+ % % which is better for IO performance .
114
+ -spec to_iolist (cdata () | exml_stream :element () | [exml_stream :element ()], prettify ()) -> iodata ().
112
115
to_iolist (# xmlel {} = Element , Pretty ) ->
113
116
to_binary_nif (Element , Pretty );
114
- to_iolist ([Element ], Pretty ) ->
115
- to_iolist (Element , Pretty );
116
- to_iolist ([Head | _ ] = Elements , Pretty ) ->
117
- [Last | RevChildren ] = lists :reverse (tl (Elements )),
118
- case {Head , Last } of
119
- {# xmlstreamstart {name = Name , attrs = Attrs },
120
- # xmlstreamend {name = Name }} ->
121
- Element = # xmlel {name = Name , attrs = Attrs ,
122
- children = lists :reverse (RevChildren )},
123
- to_binary_nif (Element , Pretty );
124
- _ ->
125
- [to_iolist (El , Pretty ) || El <- Elements ]
126
- end ;
127
117
to_iolist (# xmlstreamstart {name = Name , attrs = Attrs }, _Pretty ) ->
128
118
Result = to_binary_nif (# xmlel {name = Name , attrs = Attrs }, not_pretty ),
129
119
FrontSize = byte_size (Result ) - 2 ,
@@ -132,7 +122,21 @@ to_iolist(#xmlstreamstart{name = Name, attrs = Attrs}, _Pretty) ->
132
122
to_iolist (# xmlstreamend {name = Name }, _Pretty ) ->
133
123
[<<" </" >>, Name , <<" >" >>];
134
124
to_iolist (# xmlcdata {content = Content }, _Pretty ) ->
135
- exml_nif :escape_cdata (Content ).
125
+ exml_nif :escape_cdata (Content );
126
+ to_iolist ([Element ], Pretty ) ->
127
+ to_iolist (Element , Pretty );
128
+ to_iolist ([# xmlstreamstart {name = Name , attrs = Attrs } | Tail ] = Elements , Pretty ) ->
129
+ [Last | RevChildren ] = lists :reverse (Tail ),
130
+ case Last of
131
+ # xmlstreamend {name = Name } ->
132
+ % % Add extra nesting for streams so pretty-printing would be indented properly
133
+ Element = # xmlel {name = Name , attrs = Attrs , children = lists :reverse (RevChildren )},
134
+ to_binary_nif (Element , Pretty );
135
+ _ ->
136
+ [to_iolist (El , Pretty ) || El <- Elements ]
137
+ end ;
138
+ to_iolist (Elements , Pretty ) when is_list (Elements ) ->
139
+ [to_iolist (El , Pretty ) || El <- Elements ].
136
140
137
141
-spec to_binary_nif (element (), prettify ()) -> binary ().
138
142
to_binary_nif (# xmlel {} = Element , Pretty ) ->
0 commit comments