Section numbering using xmerl:export
Mikael Karlsson
mikael.karlsson@REDACTED
Fri Sep 13 21:31:20 CEST 2002
Hi Vlad,
thanks for your routine. If I understand it right it is a map function
of the "RoseTree" like structure of xmlElements. The problem was
that I needed to now where in the tree I was in order to set the
chapter numbers correctly. With a slight modification, adding
accumulator and folding top->down as well as left right I could
get things in place.
/Mikael
%% mapfoldxml
%% Fun is fun(Old#xmlElement, OldAccu) -> {New#xmlElement, NewAccu}
mapfoldxml(Fun, Accu0, #xmlElement{}=E) ->
{C1,Accu1} = Fun(E, Accu0),
{C2,Accu2} = mapfoldxml(Fun, Accu1, lists:flatten(C1#xmlElement.content)),
{C1#xmlElement{content=C2},Accu2};
mapfoldxml(Fun, Accu, List) when list(List) ->
AFun = fun(E,A) -> mapfoldxml(Fun, A, E) end,
lists:mapfoldl(AFun, Accu, List);
mapfoldxml(_Fun, Accu, E) ->
{E,Accu}.
changetitle(A) ->
Afun = fun changecount/2,
{E, Acc} = mapfoldxml(Afun, {0,0,0}, A),
E.
changecount(#xmlElement{name=title}=E, {A,B,C})->
case E#xmlElement.parents of
[{section,_},{section,_},{section,_},{article,_} |_] ->
addheader(E,{A,B,C+1});
[{section,_},{section,_},{article,_} |_] ->
addheader(E,{A,B+1,0});
[{section,_},{article,_} |_] ->
addheader(E,{A+1,0,0});
_ ->
{E,{A,B,C}}
end;
changecount(E, Acc)->{E,Acc}.
addheader(#xmlElement{name=title,content=[#xmlText{}=T1|_]}= E, Chapters)->
NewHeader = chapterstring(Chapters)++ " " ++ T1#xmlText.value,
NewAtts = addid(E#xmlElement.attributes, Chapters),
{E#xmlElement{content=[T1#xmlText{value=NewHeader}],
attributes = NewAtts},Chapters}.
chapterstring({A,0,0})->integer_to_list(A);
chapterstring({A,B,0})->integer_to_list(A)++"."++ integer_to_list(B);
chapterstring({A,B,C})->integer_to_list(A) ++ "." ++
integer_to_list(B) ++ "." ++
integer_to_list(C).
torsdag 29 augusti 2002 12:09 skrev Vlad Dumitrescu:
> Hi,
>
> I don't know about the xmerl details, but I think it might be risky to rely
> on a implementation dependent feature... Of course, this depends on your
> application's use.
>
> The safe way would be going through the tree and numbering the nodes along
> the path. I have written a small routine that will traverse a xml tree and
> call a fun with every node. I think it might help you too (or others).
>
> best regards,
> Vlad
>
> %%% File : xmerl_util.erl
> %%% Author : <Vlad_dumitrescu@REDACTED>
> %%% Description :
> %%% Created : 14 Aug 2002 by <Vlad_dumitrescu@REDACTED>
>
> -module(xmerl_util).
> -export([traverse/2]).
> -include("xmerl.hrl").
>
> %% convert an xml doc into another
> %%
> %% Fun should return a xmlXXX record, or a list of such records
>
> traverse(#xmlElement{content=C}=E, Fun) ->
> C1 = lists:flatten(traverse(C, Fun)),
> Fun(E#xmlElement{content=C1});
> traverse(List, Fun) when list(List) ->
> AFun = fun(E) -> traverse(E, Fun) end,
> lists:map(AFun, List);
> traverse(E, _Fun) ->
> E.
More information about the erlang-questions
mailing list