-
Notifications
You must be signed in to change notification settings - Fork 0
/
xml.erl
64 lines (52 loc) · 2.19 KB
/
xml.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
-module(xml).
-export([decode/1]).
% Первичное преобразование и самая простая проверка
decode(String) ->
case{String} of
{<<>>} -> error;
{_} -> decode(String, {<<>>, [], []})
end.
% Основное тело программы, где определяются теги и контент
decode(<<"</", T/binary>>, {Tag, Attrib, Content}) ->
{Bin, {Tag, []}} = tag(T, {<<>>, []}),
case{Bin == <<>>} of
{false} -> {Bin, {Tag, Attrib, Content}};
{true} -> {Tag, Attrib, Content}
end;
decode(<<"<", T/binary>>, {<<>>, [], Cont}) ->
{Bin, {Tag, Att}} = tag(T, {<<>>, []}),
decode(Bin, {Tag, Att, Cont});
decode(Bin, {Tag, Attrib, []}) ->
{T, Cont} = content(Bin, <<>>, []),
decode(T, {Tag, Attrib, Cont}).
% Обработка тегов
tag(<<">", T/binary>>, {Tag, Att}) ->
{T, {Tag, reverse(Att)}};
tag(<<" ", T/binary>>, {Tag, Acc}) ->
{Bin, Att} = attribute(T, {<<>>, <<>>}),
tag(Bin, {Tag, [Att | Acc]});
tag(<<H:1/binary, T/binary>>, {Tag, []}) ->
tag(T, {<<Tag/binary, H/binary>>, []}).
% Обработка атрибутов тегов
attribute(<<"=\"", H:1/binary, T/binary>>, {Name, <<>>}) ->
attribute(T, {Name, H});
attribute(<<"\"", T/binary>>, Acc) ->
{T, Acc};
attribute(<<H:1/binary, T/binary>>, {Name, <<>>}) ->
attribute(T, {<<Name/binary, H/binary>>, <<>>});
attribute(<<H:1/binary, T/binary>>, {Name, Value}) ->
attribute(T, {Name, <<Value/binary, H/binary>>}).
% Обработка контента и перенаправление вложений в основную часть
content(<<"</", T/binary>>, <<>>, Cont) ->
{<<"</", T/binary>>, reverse(Cont)};
content(<<"<", T/binary>>, <<>>, Cont) ->
{Bin, NextLevel} = decode(<<"<", T/binary>>),
content(Bin, <<>>, [NextLevel|Cont]);
content(<<"<", T/binary>>, Acc, Cont) ->
content(<<"<", T/binary>>, <<>>, [Acc|Cont]);
content(<<H:1/binary, T/binary>>, Acc, Cont) ->
content(T, <<Acc/binary, H/binary>>, Cont).
% Помогает переворачивать списки
reverse(List1) -> reverse(List1,[]).
reverse([], List2) -> List2;
reverse([H|T], List2) -> reverse(T, [H|List2]).