Как я XML-кодирую строку в Erlang?

У меня есть строка erlang, которая может содержать символы как и "<и так далее:

1> Unenc = "string & \"stuff\" <".
ok

Есть ли функция Erlang где-нибудь, которая анализирует строку и кодирует все необходимые объекты HTML/XML, такие как:

2> Enc = xmlencode(Unenc).
"string &amp; &quot;stuff&quot; &lt;".

?

Мой вариант использования для относительно коротких строк, которые прибывают из ввода данных пользователем. Выходные строки функции xmlencode будут содержанием атрибутов XML:

<company name="Acme &amp; C." currency="&euro;" />

Заключительный XML будет отправлен по проводу соответственно.

8
задан ettore 29 July 2010 в 18:07
поделиться

3 ответа

В распределении Эрланга есть функция, которая избегает угловых скобок и амперсанды, но это не задокументировано, поэтому, вероятно, не лучше на него полагаться:

1> xmerl_lib:export_text("string & \"stuff\" <").
"string &amp; \"stuff\" &lt;"

Если вы хотите создавать / кодировать структуры XML (а не просто кодировать одну строку), тогда xmerl API будет хорошим вариантом , например

2> xmerl:export_simple([{foo, [], ["string & \"stuff\" <"]}], xmerl_xml).
["<?xml version=\"1.0\"?>",
 [[["<","foo",">"],
   ["string &amp; \"stuff\" &lt;"],
   ["</","foo",">"]]]]
4
ответ дан 5 December 2019 в 21:15
поделиться

Если ваши потребности просты, вы можете сделать это с помощью карты символов в строке.

quote($<) -> "&lt;";
quote($>) -> "&gt;";
quote($&) -> "&amp;";
quote($") -> "&quot;";
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 ++ "&lt;"); % euro symbol
xmlencode([226,130,172|T], Acc) -> xmlencode(T, Acc ++ "&#8364;");
xmlencode([OneChar|T], Acc) -> xmlencode(T, lists:flatten([Acc,OneChar])). 

Хотя я бы предпочел не изобретать колесо, если это возможно.

dsmith: Строка, которую вы используете, обычно представляет собой список кодовых точек Unicode (т.е. список чисел), и поэтому любая конкретная кодировка байта не имеет значения. Вам нужно беспокоиться о конкретных кодировках, только если вы работаете непосредственно с двоичными файлами.

Чтобы пояснить, кодовая точка Unicode для символа евро (десятичное число 8364) будет одним элементом в вашем списке. Поэтому вы можете поступить следующим образом:

xmlencode([8364|T], Acc) -> xmlencode(T, Acc ++ "&#8364;"); 
2
ответ дан 5 December 2019 в 21:15
поделиться

Я не знаю ни об одном из включенных пакетов OTP. Однако модуль mochiweb_html от Mochiweb: имеет функцию экранирования: mochiweb_html.erl она обрабатывает списки, двоичные файлы и атомы.

А для кодирования url посмотрите модуль mochiweb_util: mochiweb_util.erl с его функцией urlescape.

Вы можете использовать любую из этих библиотек, чтобы получить то, что вам нужно.

1
ответ дан 5 December 2019 в 21:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: