1%%%------------------------------------------------------------------- 2%%% File : motorcycles2html.erl 3%%% Author : Bertil Karlsson <bertil@localhost.localdomain> 4%%% Description : 5%%% 6%%% Created : 2 Sep 2004 by Bertil Karlsson <bertil@localhost.localdomain> 7%%%------------------------------------------------------------------- 8-module(motorcycles2html). 9 10-include_lib("xmerl/include/xmerl.hrl"). 11 12-import(xmerl_xs, 13 [ xslapply/2, value_of/1, select/2, built_in_rules/2 ]). 14 15-export([process_xml/1,process_to_file/2,process_to_file/1]). 16 17process_xml(Doc) -> 18 template(Doc). 19 20process_to_file(FileName) -> 21 process_to_file(FileName,'motorcycles.xml'). 22 23process_to_file(FileName,XMLDoc) -> 24 case file:open(FileName,[write]) of 25 {ok,IOF} -> 26 {XMLContent,_} = xmerl_scan:file(XMLDoc), 27 TransformedXML=process_xml(XMLContent), 28 io:format(IOF,"~s",[TransformedXML]), 29 file:close(IOF); 30 {error,Reason} -> 31 io:format("could not open file due to ~p.~n",[Reason]) 32 end. 33 34%%% templates 35template(E = #xmlElement{name='motorcycles'}) -> 36 [ "<head>\n<title>motorcycles</title>\n</head>\n", 37 "<body>\n", 38 "<h1>Used Motorcycles</h1>\n", 39 "<ul>\n", 40 remove_duplicates(value_of(select("bike/name/manufacturer",E))), 41 "\n</ul>\n", 42 sort_by_manufacturer(xslapply(fun template/1, E)), 43 "</body>\n", 44 "</html>\n"]; 45template(E = #xmlElement{name='bike'}) -> 46 {value_of(select("name/manufacturer",E)),["<dt>",xslapply(fun template/1,select("name",E)),"</dt>", 47 "<dd><ul>\n", 48 "<li style=\"color:green\">Manufacturing year: ",xslapply(fun template/1,select("@year",E)),"</li>\n", 49 "<li style=\"color:red\">Color: ",xslapply(fun template/1,select("@color",E)),"</li>\n", 50 "<li style=\"color:blue\">Shape : ",xslapply(fun template/1,select("@condition",E)),"</li>\n", 51 "</ul></dd>\n"]}; 52template(E) -> built_in_rules(fun template/1, E). 53 54 55%%%%%%%%%%% helper routines 56 57%% sorts on the bike name element, unwraps the bike information and 58%% inserts a line feed and indentation on each bike element. 59sort_by_manufacturer(L) -> 60 Tuples=[X1||X1={_,_} <- L], 61 SortedTS = lists:keysort(1,Tuples), 62 InsertRefName_UnWrap= 63 fun([{[Name],V}|Rest],Name,F)-> 64 [V|F(Rest,Name,F)]; 65 ([{[Name],V}|Rest],_PreviousName,F) -> 66 [["<a name=\"",Name,"\"></>"],V|F(Rest,Name,F)]; 67 ([],_,_) -> [] 68 end, 69 SortedRefed=InsertRefName_UnWrap(SortedTS,no_name,InsertRefName_UnWrap), 70% SortedTs=[Y||{X,Y}<-lists:keysort(1,Tuples)], 71 WS = "\n ", 72 Fun=fun([H|T],Acc,F)-> 73 F(T,[H,WS|Acc],F); 74 ([],Acc,_F)-> 75 lists:reverse([WS|Acc]) 76 end, 77 if length(SortedRefed) > 0 -> 78 Fun(SortedRefed,[],Fun); 79 true -> [] 80 end. 81 82 83%% removes all but the first of an element in L and inserts a html 84%% reference for each list element. 85remove_duplicates(L) -> 86 remove_duplicates(L,[]). 87 88remove_duplicates([],Acc) -> 89 make_ref(lists:sort(lists:reverse(Acc))); 90remove_duplicates([A|L],Acc) -> 91 case lists:delete(A,L) of 92 L -> 93 remove_duplicates(L,[A|Acc]); 94 L1 -> 95 remove_duplicates([A|L1],[Acc]) 96 end. 97 98make_ref([]) -> []; 99make_ref([H]) when is_atom(H) -> 100 "<ul><a href=\"#"++atom_to_list(H)++"\">"++atom_to_list(H)++"</a></ul>"; 101make_ref([H]) when is_list(H) -> 102 "<ul><a href=\"#"++H++"\">\s"++H++"</a></ul>"; 103make_ref([H|T]) when is_atom(H) -> 104 ["<ul><a href=\"#"++atom_to_list(H)++"\">\s"++atom_to_list(H)++",\n</a></ul>" 105 |make_ref(T)]; 106make_ref([H|T]) when is_list(H) -> 107 ["<ul><a href=\"#"++H++"\">\s"++H++",\n</a></ul>"|make_ref(T)]. 108