dtsps2098 2016-10-28 16:35
浏览 77
已采纳

SimpleXML元素对象空白

I get an XML response from remote service. I call echo htmlentities($xml); and get the XML as formatted beneath.

However, if I want it as an SimpleXML array, I get this output (trimmed):

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

How do I access the <resData> object?

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条回答 默认 最新

  • douou1872 2016-10-28 16:50
    关注

    Issue of namespace :)

    To get your data, use $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)
     **/
    

    Edit: Add my tips:

    /**
     * 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);
    }
    

    How to use it:

    // 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>';
    

    Result:

    <?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>
    

    And the data (example):

    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)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 目详情-五一模拟赛详情页
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line