生成XML文档时CDATA段中含有]]>怎么办?
这是个有意思的问题,包含在CDATA标签<![CDATA[ ... ]]>之间的内容会被XML解析器忽略,这样就不需要对内容中出现的 <>&等字符进行转义(<>&)。
但是内容中一旦出现]]>,就会导致XML解析失败,因为CDATA不允许嵌套。
解决的办法不止一个,我采用把 ]]>拆开放入两个CDATA中的简单办法,下面是PHP的实现:
function XmlCDATAStr($s)
{
$a = explode(']]>',$s);
return XmlSafeStr(implode(']]]]><![CDATA[>',$a));
}
上面用到了前文提到的XmlSafeStr()函数来过滤非法的XML字符。
有更好的办法请一定告诉我 :)
suozixie said,
2007/1/11 @ 17:54
博客部落解决了谢谢
$strTitle = str_replace(']]>', ']]>', $strTitle);
Nukq said,
2007/1/11 @ 18:00
嗯?你的代码是不是贴错了? :P
suozixie said,
2007/1/11 @ 20:14
如果]]>是用来显示的话,可以这样做
$strTitle = str_replace(']]>', ']]>', $strTitle);
本来打开http://www.blogblo.com/blogblo.php?id=26会报错,原因是你blog的rss中的文章标题中的“>”没有被转义(一般的rss的文章标题和内容是htmlentities过的,不会出现]]>),所以抓取的时候就导致CDATA中的出现了]]>, 现在我加了$strTitle = str_replace(']]>', ']]&>;', $strTitle);,问题就解决了。
抓你这篇文章时候暴露了blogblo的一个潜在bug,要说一声谢谢。
不过在你blog上发回复好麻饭啊为了显示]]>要输入]]&gt;
我想应该把回复htmlentities转义一下吧~_~,我不知道回复可不可一插入js,否者...
Nukq said,
2007/1/11 @ 20:25
如果对CDATA内的内容再做转义,那就不符合CDATA的本意了,所以我拆开放入两个CDATA中。
wordpress的内部字符处理很乱,看不明白 呵呵,
所以帖代码上来往往显示的面目全非 :(
昨天在blogblo添加了这个种子,结果加载了半天没反应,原来是这个bug 啊
suozixie said,
2007/1/11 @ 20:42
在CDATA里的字符是不用,我刚意识到我说错了
但是如果CDATA中是html code 而且 ]]>是用来显示而不是之类的标签,是不是应该转为]]>的吧(html tag中应该不会用到的吧,我想是一般用来显示的)
但是你的title没用CDATA也没转义,且恰好又是关于]]>的,太巧了和,所以blogblo的xajax出错了。
用你方法改进xajax那应该是最根本的解决办法了,说到底是毕竟是xajax
Nukq said,
2007/1/11 @ 20:47
嗯,作为html显示的时候肯定要转义的
另外: 我看了我的rss输出。其中 titile虽没有包含在CDATA中, 但是已经转义了啊。
<title>生成XML文档时CDATA段中含有]]>怎么办?</title>
Nukq said,
2007/1/11 @ 20:52
我想:不管是转义还是 原样放入CDATA中,你用xml库得到后的数据都是未转义的。
所以显示的时候还是要htmlentities处理的。
Anonymous said,
2007/1/11 @ 20:53
用你方法(很通用)改进xajax那应该是最根本的解决办法了,说到底是毕竟是xajax bug。
你们做的东东很精致
很想和你交个朋友,我的QQ:95210236。有机会能见个面最好了
suozixie said,
2007/1/11 @ 20:57
htmlentities处理后文章中的图片和段落就没了连也没了。
现在的做法是 $strDescription = strip_tags($strDescription, "");
Nukq said,
2007/1/11 @ 21:05
对标题用 htmlspecialchars()处理就够了
对文章内容,因为是html格式,所以可以直接输出,但是这样有隐含的安全问题,建议对内容进行必要的修正和过滤,比较理想的是使用Tidy模块来处理
看我的文章:
PHP+Tidy-完美的XHTML纠错+过滤
http://nukq.malmam.com/?p=14
Nukq said,
2007/1/11 @ 21:11
加你QQ了 :P
suozixie said,
2007/1/11 @ 22:33
如果标题带引号什么的一般blog rss都已经进行了htmlentities了(sohu sina 等),我再加就两次htmlentities了,显示不正确了。你这个除外~_~
Nukq said,
2007/1/11 @ 22:40
输出XML的时候:如果没有CDATA,那么需要转义;如果有CDATA,那么不需要转义。
按照这个原则,那么你解析XML得到的标题数据肯定是 原始数据(未转义的)
如果不是,那么要么XML解析库有问题,要么对方输出的时候胡乱转义。
因此输出的做一次htmlspecialchars(),也就只做了一次而已。
如果页面显示的时候出现&xxx啥的,肯定是对方输出不标准导致的。
suozixie said,
2007/1/11 @ 23:51
如果不是,那么要么XML解析库有问题,要么对方输出的时候胡乱转义。
~~~~~~~~~~~~~~~~~~~~~~
问题就出在这,很多大的网站的rss的文章title
同时用了CDATA和&转义,而你的只用了&转义。
有点不好办~_~!
Nukq said,
2007/1/11 @ 23:54
汗~ 不按照标准,
那就无语了 -.-