2012-07-11 18 views
19

¿Hay alguna forma más elegante de escaparse de los atributos de SimpleXML en una matriz?Atributos de SimpleXML en Array

$result = $xml->xpath($xpath); 
$element = $result[ 0 ]; 
$attributes = (array) $element->attributes(); 
$attributes = $attributes[ '@attributes' ]; 

Realmente no quiero tener que recorrerlo solo para extraer el par de clave/valor. Todo lo que necesito es meterlo en una matriz y luego pasarlo. Pensé que attributes() lo habría hecho de manera predeterminada, o al menos dada la opción. Pero ni siquiera pude encontrar la solución anterior en ninguna parte, tuve que resolverlo por mi cuenta. ¿Estoy sobrecompletando esto o algo?

Editar:

Todavía estoy usando el script anterior hasta que no sepa a ciencia cierta si el acceso a la matriz @attributes es seguro o no.

Respuesta

11

No lea directamente la propiedad '@attributes', que es para uso interno. De todos modos, attributes() ya se puede utilizar como una matriz sin necesidad de "convertir" a una matriz real.

Por ejemplo:

<?php 
$xml = '<xml><test><a a="b" r="x" q="v" /></test><b/></xml>'; 
$x = new SimpleXMLElement($xml); 

$attr = $x->test[0]->a[0]->attributes(); 
echo $attr['a']; // "b" 

Si usted quiere que sea un "verdadero" matriz, vamos a tener que bucle:

$attrArray = array(); 
$attr = $x->test[0]->a[0]->attributes(); 

foreach($attr as $key=>$val){ 
    $attrArray[(string)$key] = (string)$val; 
} 
+0

Sí, pero el problema con esto es que todavía se ve a sí mismo como un elemento SimpleXML y, por lo tanto, tendrías que escribir '$ attr ['a']' en una cadena para que funcione correctamente. Estoy pasando esta matriz a otra clase que no sabe qué tipo se supone que es, solo que necesita ser una matriz. – mseancole

+0

Ah, lo tienes en la edición ... ¿El ciclo es "mejor" que el que estoy haciendo actualmente? Yo pensaría que hacerlo sin un bucle sería más rápido. – mseancole

+0

@showerhead: No sé si es mejor, pero siempre aprendí a no leer directamente la propiedad ''@ attributes''. –

0

creo que tendrá que recorrer. Puede obtenerlo en conjunto una vez que lea xml.

<?php 
function objectsIntoArray($arrObjData, $arrSkipIndices = array()) 
{ 
$arrData = array(); 

// if input is object, convert into array 
if (is_object($arrObjData)) { 
    $arrObjData = get_object_vars($arrObjData); 
} 

if (is_array($arrObjData)) { 
    foreach ($arrObjData as $index => $value) { 
     if (is_object($value) || is_array($value)) { 
      $value = objectsIntoArray($value, $arrSkipIndices); // recursive call 
     } 
     if (in_array($index, $arrSkipIndices)) { 
      continue; 
     } 
     $arrData[$index] = $value; 
    } 
} 
return $arrData; 
} 

$xmlStr = file_get_contents($xml_file); 
$xmlObj = simplexml_load_string($xmlStr); 
$arrXml = objectsIntoArray($xmlObj); 

foreach($arrXml as $attr) 
    foreach($attr as $key->$val){ 
if($key == '@attributes') .... 
} 
+1

¿Qué es 'objectsIntoArray'? Además, no debe leer los ''@ atributos'' directamente, para eso es' -> attributes() '. –

+0

Lo siento, pegué el código que faltaba en la parte superior que acaba de editar. – PoX

40

a more elegant way; que le da los mismos resultados sin necesidad de utilizar $ atributos [ ''] @attributes:

$attributes = current($element->attributes()); 
+0

Absolutamente simple, compacto y menos operaciones. –

+0

@silverskater: muy útil, ¡me funciona! Muchas gracias –

+0

Esta debería ser la respuesta – kfriend