Chad 2010-06-10
今天有个任务是要用PHP5来对比两个XML文件的内容。在PHP5里处理XML文件可以用DOM,但是对于简单的处理,用SimpleXML则更为简便。
可是,这次用以下代码读出来的文件,子节点的内容全是空的:
Code - PHPPlain Text
- $sourceFileContent = file_get_contents($sourceFileName);
- $sourceXML = new SimpleXMLElement($sourceFileContent);
- var_dump($sourceXML);
但是elements的attributes却可以读取到,这是为什么呢?我一看XML文件的内容,发现所有的elements的内容都用<![CDATA[ ]]>包起来了,也就是说,都标识成为CData1了。可以看出SimpleXML在parse XML文件内容时,把CData里的内容全都忽略了。
这该怎么处理呢?用正则表达式把CData标识去掉——这是我的第一反应。
但是,我又想,这种事情应该不会没有前人遇到过吧?为了不要“重复发明车轮”,我决定先搜搜资料。结果在PHP.net上给我找到了一个处理办法2:
Code - XML/HTMLPlain Text
- // nathan at gimpstraw dot com
- //05-Apr-2008 05:43
- //I'm using SimpleXML to process data sent back from an API request, and I ran into the CDATA problem and the error you get from html entities, and here is a solution i came up with, don't know if it's the most practical, but it's working.
- <?php
- $str = <<< XML
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <menu>
- <item>
- <title><![CDATA[Café]]></title>
- <description><![CDATA[Some description.]]></description>
- </item>
- </menu>
- XML;
- $str = preg_replace("/\<\!\[CDATA\[(.*?)\]\]\>/ies", "'[CDATA]'.base64_encode('$1').'[/CDATA]'", $str);
- $xml = new SimpleXMLElement($str);
- // Return item title's
- foreach ($xml->item as $item) {
- $tmp = (string) $item->title;
- $tmp = preg_replace("/\[CDATA\](.*?)\[\/CDATA\]/ies", "base64_decode('$1')", $tmp);
- echo $tmp;
- }
- ?>
真好。。。又不用自己写了。。。就这样又解决了一个问题。。。
1. CData, http://en.wikipedia.org/wiki/CDATA_section
2. SimpleXML Functions, http://php.net/manual/en/ref.simplexml.php