У меня есть строка erlang, которая может содержать символы как и "<и так далее:
1> Unenc = "string & \"stuff\" <".
ok
Есть ли функция Erlang где-нибудь, которая анализирует строку и кодирует все необходимые объекты HTML/XML, такие как:
2> Enc = xmlencode(Unenc).
"string & "stuff" <".
?
Мой вариант использования для относительно коротких строк, которые прибывают из ввода данных пользователем. Выходные строки функции xmlencode будут содержанием атрибутов XML:
<company name="Acme & C." currency="€" />
Заключительный XML будет отправлен по проводу соответственно.
В распределении Эрланга есть функция, которая избегает угловых скобок и амперсанды, но это не задокументировано, поэтому, вероятно, не лучше на него полагаться:
1> xmerl_lib:export_text("string & \"stuff\" <").
"string & \"stuff\" <"
Если вы хотите создавать / кодировать структуры XML (а не просто кодировать одну строку), тогда xmerl API будет хорошим вариантом , например
2> xmerl:export_simple([{foo, [], ["string & \"stuff\" <"]}], xmerl_xml).
["<?xml version=\"1.0\"?>",
[[["<","foo",">"],
["string & \"stuff\" <"],
["</","foo",">"]]]]
Если ваши потребности просты, вы можете сделать это с помощью карты символов в строке.
quote($<) -> "<";
quote($>) -> ">";
quote($&) -> "&";
quote($") -> """;
quote(C) -> C.
Тогда вы сделаете
1> Raw = "string & \"stuff\" <".
2> Quoted = lists:map(fun quote/1, Raw).
Но Quoted
не будет плоским списком, что все еще хорошо, если вы собираетесь отправить его в файл или в качестве http-ответа. То есть, смотрите io-списки Erlang.
В более поздних выпусках Erlang появились функции кодирования-декодирования многобайтовых представлений utf8 в широкобайтовые/кодовые, см. модуль erlang unicode.
Переформатированные комментарии, чтобы примеры кода выделялись:
ettore: Это вроде того, что я делаю, хотя мне нужно поддерживать многобайтовые символы. Вот мой код:
xmlencode([], Acc) -> Acc;
xmlencode([$<|T], Acc) -> xmlencode(T, Acc ++ "<"); % euro symbol
xmlencode([226,130,172|T], Acc) -> xmlencode(T, Acc ++ "€");
xmlencode([OneChar|T], Acc) -> xmlencode(T, lists:flatten([Acc,OneChar])).
Хотя я бы предпочел не изобретать колесо, если это возможно.
dsmith: Строка, которую вы используете, обычно представляет собой список кодовых точек Unicode (т.е. список чисел), и поэтому любая конкретная кодировка байта не имеет значения. Вам нужно беспокоиться о конкретных кодировках, только если вы работаете непосредственно с двоичными файлами.
Чтобы пояснить, кодовая точка Unicode для символа евро (десятичное число 8364) будет одним элементом в вашем списке. Поэтому вы можете поступить следующим образом:
xmlencode([8364|T], Acc) -> xmlencode(T, Acc ++ "€");
Я не знаю ни об одном из включенных пакетов OTP. Однако модуль mochiweb_html от Mochiweb: имеет функцию экранирования: mochiweb_html.erl она обрабатывает списки, двоичные файлы и атомы.
А для кодирования url посмотрите модуль mochiweb_util: mochiweb_util.erl с его функцией urlescape.
Вы можете использовать любую из этих библиотек, чтобы получить то, что вам нужно.