如何在Erlang中对字符串进行XML编码?

时间:2010-07-26 21:06:12

标签: xml erlang html-encode xml-encoding

我有一个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将通过网络发送。

3 个答案:

答案 0 :(得分:4)

Erlang发行版中有一个函数可以转义尖括号和&符号,但是没有记录,所以最好不要依赖它:

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",">"]]]]

答案 1 :(得分:2)

如果您的需求很简单,您可以使用字符串中字符的映射来完成此操作。

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回复,这仍然没有问题。即看Erlang的io-lists。

在最近的Erlang版本中,现在有用于多字节utf8到宽字节/代码点表示的编码 - 解码函数,请参阅erlang unicode module


重新格式化的评论,使代码示例脱颖而出:

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代码点列表(即数字列表),因此任何给定的字节编码都无关紧要。如果您直接使用二进制文件,则只需要担心特定的编码。

为了澄清,欧元符号(十进制8364)的Unicode代码点将是列表中的单个元素。所以你会这样做:

xmlencode([8364|T], Acc) -> xmlencode(T, Acc ++ "&#8364;"); 

答案 2 :(得分:1)

我不知道所包含的OTP包装中的一个。但是Mochiweb的mochiweb_html模块:有一个转义函数:mochiweb_html.erl它处理列表,二进制文件和原子。

对于url编码结帐mochiweb_util模块:mochiweb_util.erl及其urlescape函数。

您可以使用其中任何一个库来获取所需内容。