Ver Mensaje Individual
  #1 (permalink)  
Antiguo 07/09/2011, 03:29
Avatar de cluster28
cluster28
 
Fecha de Ingreso: enero-2008
Ubicación: Donostia - San Sebastián
Mensajes: 756
Antigüedad: 16 años, 10 meses
Puntos: 32
Parsear xml con DomDocument

Necesito parsear unos xml que me devuelve un webservice.

Encontré ésta clase que parsea los xml y funciona bien.

Código PHP:
class MyDOMDocument extends DOMDocument
{
    public function 
toArray(DOMNode $oDomNode null)
    {
        
// return empty array if dom is blank
        
if (is_null($oDomNode) && !$this->hasChildNodes()) {
            return array();
        }
        
$oDomNode = (is_null($oDomNode)) ? $this->documentElement $oDomNode;
        if (!
$oDomNode->hasChildNodes()) {
            
$mResult $oDomNode->nodeValue;
        } else {
            
$mResult = array();
            foreach (
$oDomNode->childNodes as $oChildNode) {
                
// how many of these child nodes do we have?
                // this will give us a clue as to what the result structure should be
                
$oChildNodeList $oDomNode->getElementsByTagName($oChildNode->nodeName); 
                
$iChildCount 0;
                
// there are x number of childs in this node that have the same tag name
                // however, we are only interested in the # of siblings with the same tag name
                
foreach ($oChildNodeList as $oNode) {
                    if (
$oNode->parentNode->isSameNode($oChildNode->parentNode)) {
                        
$iChildCount++;
                    }
                }
                
$mValue $this->toArray($oChildNode);
                
$sKey   = ($oChildNode->nodeName{0} == '#') ? $oChildNode->nodeName;
                
$mValue is_array($mValue) ? $mValue[$oChildNode->nodeName] : $mValue;
                
// how many of thse child nodes do we have?
                
if ($iChildCount 1) {  // more than 1 child - make numeric array
                    
$mResult[$sKey][] = $mValue;
                } else {
                    
$mResult[$sKey] = $mValue;
                }
            }
            
// if the child is <foo>bar</foo>, the result will be array(bar)
            // make the result just 'bar'
            
if (count($mResult) == && isset($mResult[0]) && !is_array($mResult[0])) {
                
$mResult $mResult[0];
            }
        }
        
// get our attributes if we have any
        
$arAttributes = array();
        if (
$oDomNode->hasAttributes()) {
            foreach (
$oDomNode->attributes as $sAttrName=>$oAttrNode) {
                
// retain namespace prefixes
                
$arAttributes["@{$oAttrNode->nodeName}"] = $oAttrNode->nodeValue;
            }
        }
        
// check for namespace attribute - Namespaces will not show up in the attributes list
        
if ($oDomNode instanceof DOMElement && $oDomNode->getAttribute('xmlns')) {
            
$arAttributes["@xmlns"] = $oDomNode->getAttribute('xmlns');
        }
        if (
count($arAttributes)) {
            if (!
is_array($mResult)) {
                
$mResult = (trim($mResult)) ? array($mResult) : array();
            }
            
$mResult array_merge($mResult$arAttributes);
        }
        
$arResult = array($oDomNode->nodeName=>$mResult);
        return 
$arResult;
    }

El problema viene cuando hay etiquetas con el mismo nombre. Sólo me devuelve una.

He estado haciendo pruebas pero no consigo resolverlo.

Código XML:
Ver original
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <epp xmlns="http://www.eurid.eu/xml/epp/epp-1.0" xmlns:domain="http://www.eurid.eu/xml/epp/domain-1.0" xmlns:extendedInfo="http://www.eurid.eu/xml/epp/extendedInfo-1.0">
  3.   <response>
  4.     <result code="1000">
  5.       <msg>Command completed successfully</msg>
  6.     </result>
  7.     <resData>
  8.       <domain:infData>
  9.         <domain:name>pruebas.eu</domain:name>
  10.         <domain:roid>5767282-EURID</domain:roid>
  11.         <domain:status s="ok"/>
  12.         <domain:registrant>c10470138</domain:registrant>
  13.         <domain:contact type="billing">c887112</domain:contact>
  14.         <domain:contact type="onsite">c10470137</domain:contact>
  15.         <domain:ns>
  16.           <domain:hostAttr>
  17.             <domain:hostName>dns1.loquemedelagana.com</domain:hostName>
  18.           </domain:hostAttr>
  19.           <domain:hostAttr>
  20.             <domain:hostName>dns2.loquemedelagana.com</domain:hostName>
  21.           </domain:hostAttr>
  22.         </domain:ns>
  23.         <domain:clID>t000657</domain:clID>
  24.         <domain:crID>t000657</domain:crID>
  25.         <domain:crDate>2010-06-01T15:12:33.000Z</domain:crDate>
  26.         <domain:upID>t000657</domain:upID>
  27.         <domain:upDate>2010-06-01T15:12:33.000Z</domain:upDate>
  28.         <domain:exDate>2012-06-30T21:59:59.999Z</domain:exDate>
  29.       </domain:infData>
  30.     </resData>
  31.     <extension>
  32.       <extendedInfo:infData>
  33.         <extendedInfo:onhold>false</extendedInfo:onhold>
  34.         <extendedInfo:quarantined>false</extendedInfo:quarantined>
  35.       </extendedInfo:infData>
  36.     </extension>
  37.     <trID>
  38.       <svTRID>eurid-0</svTRID>
  39.     </trID>
  40.   </response>
  41. </epp>

Por ejemplo <domain:contact>

Resultado:

Código HTML:
Array
(
    [epp] => Array
        (
            [0] => 

            [response] => Array
                (
                    [0] => 
  
                    [result] => Array
                        (
                            [0] => 
    
                            [msg] => Command completed successfully
                            [@code] => 1000
                        )

                    [resData] => Array
                        (
                            [0] => 
    
                            [domain:infData] => Array
                                (
                                    [0] => 
      
                                    [domain:name] => pruebas.eu
                                    [domain:roid] => 5767282-EURID
                                    [domain:status] => Array
                                        (
                                            [@s] => ok
                                        )

                                    [domain:registrant] => c10470138
           ------------------>[domain:contact] => Array
                                        (
                                            [0] => c10470137
                                            [@type] => onsite
                                        )

                                    [domain:ns] => Array
                                        (
                                            [0] => 
        
                                            [domain:hostAttr] => Array
                                                (
                                                    [0] => 
          
                                                    [domain:hostName] => dns2.loquemedelagana.com
                                                )

                                        )

                                    [domain:clID] => t000657
                                    [domain:crID] => t000657
                                    [domain:crDate] => 2010-06-01T15:12:33.000Z
                                    [domain:upID] => t000657
                                    [domain:upDate] => 2010-06-01T15:12:33.000Z
                                    [domain:exDate] => 2012-06-30T21:59:59.999Z
                                )

                        )

                    [extension] => Array
                        (
                            [0] => 
    
                            [extendedInfo:infData] => Array
                                (
                                    [0] => 
      
                                    [extendedInfo:onhold] => false
                                    [extendedInfo:quarantined] => false
                                )

                        )

                    [trID] => Array
                        (
                            [0] => 
    
                            [svTRID] => eurid-0
                        )

                )

            [@xmlns] => http://www.eurid.eu/xml/epp/epp-1.0
        )

)
Gracias.

SOLUCIÓN: quitar los : de las etiquetas. Pasa lo mismo que con simplexml.

Yo uso este código:

Código PHP:
//Arreglo de xml
        
$xml=preg_replace('|<([/\w]+)(:)|m','<$1',$xml);
        
$xml=preg_replace('|(\w+)(:)(\w+=\&quot;)|m','$1$3',$xml); 

Última edición por cluster28; 07/09/2011 a las 04:35 Razón: SOLUCIONADO