Как мне XML-кодировать строку в Erlang? - PullRequest
8 голосов
/ 27 июля 2010

У меня есть строка erlang, которая может содержать такие символы, как & "<и т. Д .: </p>

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 будет отправлен по сети соответствующим образом.

Ответы [ 3 ]

4 голосов
/ 27 июля 2010

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

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

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

2> xmerl:export_simple([{foo, [], ["string & \"stuff\" <"]}], xmerl_xml).
["<?xml version=\"1.0\"?>",
 [[["<","foo",">"],
   ["string &amp; \"stuff\" &lt;"],
   ["</","foo",">"]]]]
2 голосов
/ 27 июля 2010

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

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 теперь есть функции кодирования-декодирования для многобайтовых представлений 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;"); 
1 голос
/ 28 июля 2010

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

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

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

...