SimpleXML元素对象空白

时间:2016-10-28 16:35:47

标签: php xml simplexml

我从远程服务获得XML响应。我调用echo htmlentities($xml);并将格式化为XML格式。

但是,如果我想将它作为SimpleXML数组,我得到这个输出(修剪):

Array
(
    [response] => 
    [result] => 
    [msg] => Command completed successfully
    [resData] => 
    [trID] => 
    [clTRID] => 75d5f6b852e509abd44395ae3caa3b65
    [svTRID] => live-5808720e-101816-1
)

如何访问<resData>对象?

Returned XML:

<?xml version="1.0" encoding="utf-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
    <response>
        <result code="1000">
            <msg>Command completed successfully</msg>
        </result>
        <resData>
            <ext-contact:lstData xmlns:ext-contact="http://www.heartinternet.co.uk/whapi/ext-contact-2.0">
                <ext-contact:contact>
                    <ext-contact:id>3ec46e4d65ff535a</ext-contact:id>
                    <ext-contact:name>John Smith</ext-contact:name>
                    <ext-contact:org>domain-name.com</ext-contact:org>
                    <ext-contact:addr><ext-contact:street>2 Fairways House</ext-contact:street>
                    <ext-contact:pc>Post Code</ext-contact:pc>
                </ext-contact:addr>
                <ext-contact:email>email@domain-name.com</ext-contact:email>
            </ext-contact:contact>
        </ext-contact:lstData>
    </resData>
    <trID>
        <clTRID>75d5f6b852e509abd44395ae3caa3b65</clTRID>
        <svTRID>live-5808720e-101498-1</svTRID>
    </trID>
</response>
</epp>

1 个答案:

答案 0 :(得分:1)

命名空间问题:)

要获取数据,请使用$x->response->resData->children('http://www.heartinternet.co.uk/whapi/ext-contact-2.0')

$x = simplexml_load_string($xml);

// get the list of namespaces
$ns = $x->getNamespaces(true);
var_dump($ns);
/** RETURN:
 * array (size=2)
 *   '' => string 'urn:ietf:params:xml:ns:epp-1.0' (length=30)
 *   'ext-contact' => string 'http://www.heartinternet.co.uk/whapi/ext-contact-2.0' (length=52)
 **/

var_dump($x);
/** RETURN:
 * only some data, except ext-contract ones
 **/


var_dump($x->response->resData->children($ns['ext-contact']));
/** RETURN:
 * object(SimpleXMLElement)[5]
 *  public 'lstData' => 
 *    object(SimpleXMLElement)[2]
 *      public 'contact' => 
 *        object(SimpleXMLElement)[3]
 *          public 'id' => string '3ec46e4d65ff535a' (length=16)
 *          public 'name' => string 'John Smith' (length=10)
 *          public 'org' => string 'domain-name.com' (length=15)
 *          public 'addr' => 
 *            object(SimpleXMLElement)[6]
 *              ...
 *          public 'email' => string 'email@domain-name.com' (length=21)
 **/

编辑:添加我的提示:

/**
 * Function simplexml_unnamespace
 **
 * Unnamespace all xml with namespace provided or all list (by default)
 **
 * @param SimpleXMLElement $xml : SimpleXMLElement to be parsed
 * @param SimpleXMLElement|Array|string|null $ns = null: namespaces to be soft deleted
 * @param boolean $softDeletion = false : Delete completely the namespace or keep _ns attribute
 **
 * @author Olivares Georges <http://olivares-georges.net>
 **
 * Examples:
 *  simplexml_unnamespace($XML, 'name-space');
 *    Will remove 'name-space' namespace values 
 *  simplexml_unnamespace($XML, null, true);
 *    Will remove all namespaces (detected via $XML->getNamespaces(true) and delete them completely
 *  simplexml_unnamespace($XML->subElt, $XML);
 *    Will linearize <subElt /> elements, and use $XML to get the list of namescape (xml root element)
 */
function simplexml_unnamespace(SimpleXMLElement $xml, $ns = null, $softDeletion = false) {
    $_ns = $ns;
    $new_xml = $xml->asXml();

    if( is_null($ns) && !is_null($xml) ) {
        $ns = $xml->getNamespaces(true);
    }
    else if( $ns instanceof SimpleXMLElement ) {
        $ns = $ns->getNamespaces(true);
    }
    else if( is_string($ns) ) {
        $ns = [$ns => ''];
    }
    else if( is_array($ns) ) {
        // keep array
    }
    else {
        trigger_error('Second parameter of ' . __FUNCTION__ . ' should be null, a string or an array');
    }

    // load default 
    $ns2 = $ns;
    if( $_ns instanceof SimpleXMLElement ) {
        $ns2 = $_ns->getNamespaces(true);
    } else if( $xml instanceof SimpleXMLElement ) {
        $ns2 = $xml->getNamespaces(true);
    }

    // replace numerical keys by the value in the root declaration NS
    foreach( (array) $ns as $nsKey => $nsValue ) {
        if( is_numeric($nsKey) ) {
            if( isset($ns2[$nsValue]) ) {
                $ns[$nsValue] = $ns2[$nsValue];
            }
            unset($ns[$nsKey]);
            // remove previous key + non found values
        }
    }

    foreach( (array) $ns as $nsKey => $nsValue ) {
        $new_xml = preg_replace(
            '`<' . preg_quote($nsKey) . ':(.[^ >]+)`',
            $softDeletion ? '<$1' : '<$1 _ns="' . $nsKey . '"',
            $new_xml
        );
        $new_xml = str_replace(' xmlns:' . $nsKey . '="' . $nsValue . '"', '', $new_xml);
        $new_xml = str_replace('</' . $nsKey . ':', '</', $new_xml);
    }

    return simplexml_load_string($new_xml);
}

如何使用它:

// load XML
$initialXML = simplexml_load_string($xml);
echo '<pre>', htmlspecialchars($initialXML->asXml()), '</pre>';

echo '<hr />';
// Unnamespace function examples:

echo '<h2>Unnamespace - initial root - NS = [\'ext-contact\', \'domain\', \'ext-dns\'] - keep NS reference (_ns)</h2>';
$withoutNsXml = simplexml_unnamespace($initialXML, ['ext-contact', 'domain', 'ext-dns'], false);
echo '<pre>', htmlspecialchars($withoutNsXml->asXml()), '</pre>';

echo '<hr />';

echo '<h2>Unnamespace - initial root - all NS - keep NS reference (_ns)</h2>';
$withoutNsXml = simplexml_unnamespace($initialXML /*, null, false*/);
echo '<pre>', htmlspecialchars($withoutNsXml->asXml()), '</pre>';

echo '<hr />';

echo '<h2>Unnamespace - initial root - all NS - remove completely NS reference</h2>';
$withoutNsXml = simplexml_unnamespace($initialXML, null, true);
echo '<pre>', htmlspecialchars($withoutNsXml->asXml()), '</pre>';

echo '<hr />';

echo '<h2>Unnamespace - children node - all NS - remove completely NS reference</h2>';
$withoutNsXml = simplexml_unnamespace($initialXML->command, null, true);
echo '<pre>', htmlspecialchars($withoutNsXml->asXml()), '</pre>';

结果:

<?xml version="1.0" encoding="utf-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
    <command>
        <info>
            <domain:info xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
                <domain:name>boxfreshinternet.co.uk</domain:name>
            </domain:info>
        </info>
        <extension>
            <ext-dns:info xmlns:ext-dns="heartinternet.co.uk/whapi/ext-dns-2.0"/>
        </extension>
        <clTRID>bc2cf3a9d78940cd811831a4f2effd93</clTRID>
    </command>
</epp>

Unnamespace - initial root - NS = ['ext-contact', 'domain', 'ext-dns'] - keep NS reference (_ns)

<?xml version="1.0" encoding="utf-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
    <command>
        <info>
            <info _ns="domain">
                <name _ns="domain">boxfreshinternet.co.uk</name>
            </info>
        </info>
        <extension>
            <info _ns="ext-dns"/>
        </extension>
        <clTRID>bc2cf3a9d78940cd811831a4f2effd93</clTRID>
    </command>
</epp>

Unnamespace - initial root - all NS - keep NS reference (_ns)

<?xml version="1.0" encoding="utf-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
    <command>
        <info>
            <info _ns="domain">
                <name _ns="domain">boxfreshinternet.co.uk</name>
            </info>
        </info>
        <extension>
            <info _ns="ext-dns"/>
        </extension>
        <clTRID>bc2cf3a9d78940cd811831a4f2effd93</clTRID>
    </command>
</epp>

Unnamespace - initial root - all NS - remove completely NS reference

<?xml version="1.0" encoding="utf-8"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
    <command>
        <info>
            <info>
                <name>boxfreshinternet.co.uk</name>
            </info>
        </info>
        <extension>
            <info/>
        </extension>
        <clTRID>bc2cf3a9d78940cd811831a4f2effd93</clTRID>
    </command>
</epp>

Unnamespace - children node - all NS - remove completely NS reference

<?xml version="1.0"?>
<command>
        <info>
            <info>
                <name>boxfreshinternet.co.uk</name>
            </info>
        </info>
        <extension>
            <info/>
        </extension>
        <clTRID>bc2cf3a9d78940cd811831a4f2effd93</clTRID>
    </command>

数据(例子):

object(SimpleXMLElement)[5]
  public 'lstData' => 
    object(SimpleXMLElement)[2]
      public 'contact' => 
        object(SimpleXMLElement)[3]
          public 'id' => string '3ec46e4d65ff535a' (length=16)
          public 'name' => string 'John Smith' (length=10)
          public 'org' => string 'domain-name.com' (length=15)
          public 'addr' => 
            object(SimpleXMLElement)[6]
              ...
          public 'email' => string 'email@domain-name.com' (length=21)