2011-07-22 21 views
8

Aquí está mi código:¿Por qué SimpleXML cambia mi matriz al primer elemento de la matriz cuando lo uso?

$string = <<<XML 
<?xml version='1.0'?> 
<test> 
<testing> 
    <lol>hello</lol> 
    <lol>there</lol> 
</testing> 
</test> 
XML; 
$xml = simplexml_load_string($string); 
echo "All of the XML:\n"; 
print_r $xml; 
echo "\n\nJust the 'lol' array:"; 
print_r $xml->testing->lol; 

Salida:

All of the XML: 

SimpleXMLElement Object 
(
    [testing] => SimpleXMLElement Object 
     (
      [lol] => Array 
       (
        [0] => hello 
        [1] => there 
       ) 

     ) 

) 




Just the 'lol' array: 

SimpleXMLElement Object 
(
    [0] => hello 
) 

¿Por qué emitir sólo el [0] en lugar de la totalidad matriz? No lo entiendo

Respuesta

5

Es porque tienes dos elementos de lol. Con el fin de acceder a la segunda que tiene que hacer esto:

$xml->testing->lol[1]; 

esto le dará "no"

$xml->testing->lol[0]; 

le dará "hola"

Los niños() de la SimpleXMLElement le dará un objeto que contiene todos los hijos de un elemento, por ejemplo:

$xml->testing->children(); 

te dará una n objeto que contiene todos los elementos secundarios del elemento "prueba" SimpleXMLElement.

Si tiene que recorrer, puede utilizar el siguiente código:

foreach($xml->testing->children() as $ele) 
{ 
    var_dump($ele); 
} 

Hay más información sobre SimpleXMLElement aquí:

http://www.php.net/manual/en/class.simplexmlelement.php

+0

¿Esto le ayudó con su problema ?? –

+1

@Yattatron esto no responde el "por qué" de la pregunta en absoluto. como dices, '$ lol [1]' = "there" y '$ lol [0]' = "hello", entonces ¿por qué 'print_r ($ lol)' imprime '0 =>" hola ", 1 => "allí" '?? – chiliNUT

+0

@chiliNUT Tiene un punto muy válido. Voy a pensar y revisar mi respuesta un poco. –

6

Lo que sugiere @Yottatron es cierto, pero no en todos los casos como muestra este ejemplo:

si su XML sería así:

<?xml version='1.0'?> 
<testing> 
    <lol> 
     <lolelem>Lol1</lolelem> 
     <lolelem>Lol2</lolelem> 
     <notlol>NotLol1</lolelem> 
     <notlol>NotLol1</lolelem> 
    </lol> 
</testing> 

salida de simplexml sería:

SimpleXMLElement Object 
(
[lol] => SimpleXMLElement Object 
    (
     [lolelem] => Array 
      (
       [0] => Lol1 
       [1] => Lol2 
      ) 

     [notlol] => Array 
      (
       [0] => NotLol1 
       [1] => NotLol1 
      ) 

    ) 

) 

y escribiendo

$xml->lol->lolelem 

lo que espera que su resultado sea

Array 
(
    [0] => Lol1 
    [1] => Lol2 
) 

pero en lugar de ello, lo haría obtener:

SimpleXMLElement Object 
(
    [0] => Lol1 
) 

y por

$xml->lol->children() 

que se obtendría:

SimpleXMLElement Object 
(
[lolelem] => Array 
    (
     [0] => Lol1 
     [1] => Lol2 
    ) 

[notlol] => Array 
    (
     [0] => NotLol1 
     [1] => NotLol1 
    ) 

) 

Lo que hay que hacer si quieres sólo el lolelem de:

$xml->xpath("//lol/lolelem") 

que da este resultado (no como forma esperada pero contiene los elementos correctos)

Array 
(
    [0] => SimpleXMLElement Object 
    (
     [0] => Lol1 
    ) 

    [1] => SimpleXMLElement Object 
    (
     [0] => Lol2 
    ) 

) 
0

encontré con este problema ...

Xpath puede ser un poco lento, por lo que puede lograr el mismo efecto con un simple bucle for.

for ($i = 0; $i < count($xml->testing->lol); $i++) { 
    print_r($xml->testing->lol[$i]); 
} 
1

lo que es posible que desee hacer es utilizar la codificación JSON/decodificar

$jsonArray = Json_decode(Json_encode($xml), true); 

Con el verdadero argumento puede llamar en lugar de usar -> usar [nombre]

modo de ejemplo sería:

$xml = file("someXmlFile.xml"); 
$jsonArray = Json_decode(Json_encode($xml), true); 
foreach(jsonArray['title'] as $title){ 
    Do something with $titles 
} 

si tiene más de 1 elemento, será típico poner @attributes si los elementos han s atributos. Esto se puede contrarrestar mediante el uso de: $title = $title['@attributes']

Espero que ayude.

1

Ah sí, recuerdo que XML simple casi me está haciendo frente con este número de matrices de análisis Pruebe el siguiente código. Le dará una variedad de elementos LOL o, si acaba de obtener un único elemento LOL, también lo devolverá en una matriz.

La principal ventaja de esto es que puedes hacer algo como foreach ($ lol as $ element) y aún así funcionará en un único elemento (o en 0) LOL.

<?php 
$string = <<<XML 
<?xml version='1.0'?> 
    <test> 
    <testing> 
     <lol>hello</lol> 
     <lol>there</lol> 
    </testing> 
    </test> 
XML; 

$xml = simplexml_load_string($string); 
echo "<pre>"; 
echo "All of the XML:\n"; 
print_r($xml); 

echo "\n\nJust the 'lol' array:\n"; 

$test_lols = $xml->testing->children();    
$childcount = count($test_lols); 
if ($childcount < 2) { 
    $lol = array($test_lols->lol);     
} 
else { 
    $lol = (array) $test_lols; 
    $lol = $lol['lol']; 
    } 

print_r($lol); 
?> 
Cuestiones relacionadas