2016-10-28 10 views
0

Я получаю ответ XML от удаленного сервиса. Я вызываю echo htmlentities($xml); и получаю XML как отформатированный ниже.Объект элемента SimpleXML пустой

Однако, если я хочу его как массив 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 protected]</ext-contact:email> 
      </ext-contact:contact> 
     </ext-contact:lstData> 
    </resData> 
    <trID> 
     <clTRID>75d5f6b852e509abd44395ae3caa3b65</clTRID> 
     <svTRID>live-5808720e-101498-1</svTRID> 
    </trID> 
</response> 
</epp> 

ответ

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 protected]' (length=21) 
**/ 

Edit: Добавить мои советы:

/** 
* 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 protected]' (length=21) 
+0

Благодарим Вас за это! –

+0

Как получить доступ к второму пространству имен? EG: <домен: информация XMLNS: домен = "урна : IETF: Титулы: XML: нс: домен-1,0" > boxfreshinternet.co.uk <доб-DNS: информация XMLNS: доб-DNS = "http://www.heartinternet.co.uk/whapi/ext-dns-2.0" /> bc2cf3a9d78940cd811831a4f2effd93

+0

Я отредактировал свой ответ. Маленькая ошибка в функции :) try 'simplexml_unnamespace ($ initialXML, null, true);'. Ответ: NS 'domain', что не линеаризовано. Вы должны добавить его в ссылку или линеаризовать все NS. –