php - leer - Atributos de SimpleXML a Array
simplexmlelement php xpath (5)
Creo que tendrás que pasar. Puedes obtenerlo en una matriz una vez que leas 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'') ....
}
¿Hay alguna forma más elegante de escapar de los atributos de SimpleXML a una matriz?
$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 clave / valor. Todo lo que necesito es colocarlo en una matriz y luego transmitirlo. Habría pensado que los attributes()
lo hubieran hecho por defecto, o al menos dada la opción. Pero ni siquiera podía encontrar la solución anterior en cualquier lugar, tenía que resolverlo por mi cuenta. ¿Estoy sobre complicando esto o algo?
Editar:
Sigo usando la secuencia de comandos anterior hasta que sepa con certeza si el acceso a la matriz @attributes es seguro o no.
No lea directamente la propiedad ''@attributes''
, que es para uso interno. De todos modos, los attributes()
ya se pueden usar 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 quieres que sea una matriz "verdadera", tendrás que hacer un bucle:
$attrArray = array();
$attr = $x->test[0]->a[0]->attributes();
foreach($attr as $key=>$val){
$attrArray[(string)$key] = (string)$val;
}
Para mí debajo del método funcionó
function xmlToArray(SimpleXMLElement $xml)
{
$parser = function (SimpleXMLElement $xml, array $collection = []) use (&$parser) {
$nodes = $xml->children();
$attributes = $xml->attributes();
if (0 !== count($attributes)) {
foreach ($attributes as $attrName => $attrValue) {
$collection[''@attributes''][$attrName] = strval($attrValue);
}
}
if (0 === $nodes->count()) {
if($xml->attributes())
{
$collection[''value''] = strval($xml);
}
else
{
$collection = strval($xml);
}
return $collection;
}
foreach ($nodes as $nodeName => $nodeValue) {
if (count($nodeValue->xpath(''../'' . $nodeName)) < 2) {
$collection[$nodeName] = $parser($nodeValue);
continue;
}
$collection[$nodeName][] = $parser($nodeValue);
}
return $collection;
};
return [
$xml->getName() => $parser($xml)
];
}
Esto también me proporciona todos los atributos que no obtuve de ningún otro método.
Podrías convertir todo el documento xml en una matriz:
$array = json_decode(json_encode((array) simplexml_load_string("<response>{$xml}</response>")), true);
Para obtener más información, consulte: https://github.com/gaarf/XML-string-to-PHP-array
Una forma más elegante; te da los mismos resultados sin usar $ attributes [''@attributes''] :
$attributes = current($element->attributes());