Skip to content

Commit

Permalink
Merge pull request #7942 from fnchooft/add-xmerl-indent-module
Browse files Browse the repository at this point in the history
Add formatting module for xml output

The xmerl_xml_indent module was added to provide indented output instead of the standard xmerl_xml output.

OTP-18922
  • Loading branch information
lthor authored Jan 10, 2024
2 parents 3135cdf + 802bebd commit 53275ec
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 24 deletions.
21 changes: 16 additions & 5 deletions lib/xmerl/doc/src/xmerl_ug.xmlsrc
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

</legalnotice>

<title>xmerl</title>
Expand Down Expand Up @@ -171,7 +171,7 @@ Grand Danois\
<p>If you want to parse the XML file motorcycles.xml you run
it in the Erlang shell like:</p>
<pre>
3> {ParsResult,Misc}=xmerl_scan:file("motorcycles.xml").
3> {ParseResult,Misc}=xmerl_scan:file("motorcycles.xml").
{{xmlElement,motorcycles,
motorcycles,
[],
Expand Down Expand Up @@ -279,7 +279,7 @@ Grand Danois\
<item>Name = atom()</item>
<item>Value = IOString | atom() | integer()</item>
</list>
<p>See also reference manual for
<p>See also reference manual for
<seeerl marker="xmerl#export_simple-3">xmerl</seeerl></p>
<p>If you want to add the information about a black Harley
Davidsson 1200 cc Sportster motorcycle from 2003 that is in
Expand Down Expand Up @@ -359,6 +359,18 @@ Data =
... </pre>
<p>The result will be: </p>
<codeinclude file="new_motorcycles2.txt" tag="" type="none"></codeinclude>
<p>

The generated XML above was formatted for readability.

Another exporter which indents the code with 2 spaces can also be used.

In order to use it one only needs to change the export-module:</p>
<pre>
...
Export=xmerl:export_simple([NewRootEl],xmerl_xml_indent,[{prolog,Prolog}]),
...
</pre>
</section>

<section>
Expand Down Expand Up @@ -488,4 +500,3 @@ template(E = #xmlElement{name='bike'}) ->
elements and the 'manufacturer' elements are not in order.</p>
</section>
</chapter>

1 change: 1 addition & 0 deletions lib/xmerl/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ MODULES = $(EDOC_MODULES) \
xmerl_validate \
xmerl_xlate \
xmerl_xml \
xmerl_xml_indent \
xmerl_xpath_lib \
xmerl_xpath_parse \
xmerl_xpath_pred \
Expand Down
1 change: 1 addition & 0 deletions lib/xmerl/src/xmerl.app.src
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
xmerl_validate,
xmerl_xlate,
xmerl_xml,
xmerl_xml_indent,
xmerl_xpath,
xmerl_xpath_lib,
xmerl_xpath_parse,
Expand Down
86 changes: 86 additions & 0 deletions lib/xmerl/src/xmerl_xml_indent.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2003-2016. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%% %CopyrightEnd%
%%

%% Description : Callback module for exporting complete or simple forms to indented XML.
%%
%% This module indents the xml with 2 spaces and a newline \n.
%% Currently the implementation does not allow it to be configured.
%% The implementation is based on the same Elixir implementation.
%% https://hexdocs.pm/xmerl_xml_indent/readme.html

-module(xmerl_xml_indent).

-export(['#xml-inheritance#'/0]).

-export(['#root#'/4,
'#element#'/5,
'#text#'/1]).

-import(xmerl_lib, [markup/3, empty_tag/2, export_text/1]).

-include("xmerl.hrl").
-include("xmerl_internal.hrl").


'#xml-inheritance#'() -> [].


%% The '#text#' function is called for every text segment.

'#text#'(Text) ->
export_text(Text).


%% The '#root#' tag is called when the entire structure has been
%% exported. It does not appear in the structure itself.

'#root#'(Data, [#xmlAttribute{name=prolog,value=V}], [], _E) ->
[V,Data];
'#root#'(Data, _Attrs, [], _E) ->
["<?xml version=\"1.0\"?>\n", Data].


%% The '#element#' function is the default handler for XML elements.

'#element#'(Tag, [], Attrs, _Parents, _E) ->
empty_tag(Tag, Attrs);
'#element#'(Tag, Data, Attrs, Parents, _E) ->
IsCharData = is_char(Data),
NewData =
case IsCharData of
true ->
LengthParents = length(Parents),
%% Push all the data over Lvl spaces.
[
indent(LengthParents + 1) ++ DataEntry
|| DataEntry <- Data
] ++ indent(LengthParents);
false ->
Data
end,
markup(Tag, Attrs, NewData).

is_char([[X|_]|_]) ->
not is_integer(X);
is_char(Data) when is_list(Data) ->
false.

indent(Level) ->
[$\n | lists:duplicate(2 * Level, $\s)].
Loading

0 comments on commit 53275ec

Please sign in to comment.