越简单越好!

PHP SimpleXML 对有CDATA的xml解析问题

发表于 2010-12-15 13:45 | 3233次阅读 0次点赞   PHP

 


a.xml

<?xml version="1.0"?>
<shows>
    <show>
        <name>The Simpsons</name>
    </show>
    <show>
        <name>That '70s Show</name>
    </show>
    <show>
        <name>Family Guy</name>
    </show>
    <show>
        <name><![CDATA[Lois & Clark]]></name>
    </show>
</shows>

 test.php

<?php
$xml_data = file_get_contents('a.xml');
$simplexml = simplexml_load_string($xml_data);
print_r($simplexml);
?>



 结果

SimpleXMLElement Object
(
    [show] => Array
        (
            [0] => SimpleXMLElement Object
                (
                    [name] => The Simpsons
                )

            [1] => SimpleXMLElement Object
                (
                    [name] => That '70s Show
                )

            [2] => SimpleXMLElement Object
                (
                    [name] => Family Guy
                )

            [3] => SimpleXMLElement Object
                (
                    [name] => SimpleXMLElement Object
                        (
                        )

                )

        )

)

 


 从网上看到的解决方法


 test.php

<?php
$xml_data = file_get_contents('a.xml');

$xml_data = uncdata($xml_data);
$simplexml = simplexml_load_string($xml_data);


print_r($simplexml);

 

function uncdata($xml)
{
    // States:
    //
    //     'out'
    //     '<'
    //     '<!'
    //     '<!['
    //     '<![C'
    //     '<![CD'
    //     '<![CDAT'
    //     '<![CDATA'
    //     'in'
    //     ']'
    //     ']]'
    //
    // (Yes, the states a represented by strings.) 
    //

    $state = 'out';

    $a = str_split($xml);

    $new_xml = '';

    foreach ($a AS $k => $v) {

        // Deal with "state".
        switch ( $state ) {
            case 'out':
                if ( '<' == $v ) {
                    $state = $v;
                } else {
                    $new_xml .= $v;
                }
            break;

            case '<':
                if ( '!' == $v  ) {
                    $state = $state . $v;
                } else {
                    $new_xml .= $state . $v;
                    $state = 'out';
                }
            break;

             case '<!':
                if ( '[' == $v  ) {
                    $state = $state . $v;
                } else {
                    $new_xml .= $state . $v;
                    $state = 'out';
                }
            break;

            case '<![':
                if ( 'C' == $v  ) {
                    $state = $state . $v;
                } else {
                    $new_xml .= $state . $v;
                    $state = 'out';
                }
            break;

            case '<![C':
                if ( 'D' == $v  ) {
                    $state = $state . $v;
                } else {
                    $new_xml .= $state . $v;
                    $state = 'out';
                }
            break;

            case '<![CD':
                if ( 'A' == $v  ) {
                    $state = $state . $v;
                } else {
                    $new_xml .= $state . $v;
                    $state = 'out';
                }
            break;

            case '<![CDA':
                if ( 'T' == $v  ) {
                    $state = $state . $v;
                } else {
                    $new_xml .= $state . $v;
                    $state = 'out';
                }
            break;

            case '<![CDAT':
                if ( 'A' == $v  ) {
                    $state = $state . $v;
                } else {
                    $new_xml .= $state . $v;
                    $state = 'out';
                }
            break;

            case '<![CDATA':
                if ( '[' == $v  ) {


                    $cdata = '';
                    $state = 'in';
                } else {
                    $new_xml .= $state . $v;
                    $state = 'out';
                }
            break;

            case 'in':
                if ( ']' == $v ) {
                    $state = $v;
                } else {
                    $cdata .= $v;
                }
            break;

            case ']':
                if (  ']' == $v  ) {
                    $state = $state . $v;
                } else {
                    $cdata .= $state . $v;
                    $state = 'in';
                }
            break;

            case ']]':
                if (  '>' == $v  ) {
                    $new_xml .= str_replace('>','&gt;',
                                str_replace('>','&lt;',
                                str_replace('"','&quot;',
                                str_replace('&','&amp;',
                                $cdata))));
                    $state = 'out';
                } else {
                    $cdata .= $state . $v;
                    $state = 'in';
                }
            break;
        } // switch

    }

    //
    // Return.
    //
        return $new_xml;

}


?>

其实只想取里头的内容,在输出前加上(string)就行。

echo (string)$simplexml->show[3]->name;


返回顶部 ^