2012-07-11 17 views
19

Czy istnieje jakiś bardziej elegancki sposób na uniknięcie atrybutów SimpleXML w tablicy?Atrybuty SimpleXML do tablicy

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

Nie chcę tego używać, aby wyodrębnić parę klucz/wartość. Wszystko, czego potrzebuję, to wprowadzić ją do tablicy, a następnie przekazać dalej. Pomyślałem, że domyślnie zrobiłby to attributes() lub przynajmniej podał opcję. Ale nigdzie nie mogłem znaleźć powyższego rozwiązania, musiałem sam to sobie wyobrazić. Czy to przez komplikowanie tego czy coś takiego?

Edit:

Nadal używam powyższy skrypt, dopóki nie wiemy na pewno, czy dostępu do tablicy @attributes jest bezpieczne, czy nie.

Odpowiedz

11

Nie należy bezpośrednio czytać właściwości '@attributes', która jest przeznaczona do użytku wewnętrznego. W każdym razie, attributes() może już być używany jako tablica bez potrzeby "konwertowania" do prawdziwej tablicy.

Na przykład:

<?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" 

Jeśli chcesz, aby być „prawdziwym” tablicę, będziesz mieć do pętli:

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

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

Tak, ale problem polega na tym, że nadal uważa się za element SimpleXML i dlatego musiałbyś typować "$ attr ['a']" na łańcuch, aby działał poprawnie. Przekazuję tę tablicę do innej klasy, która nie wie, jaki typ ma być, ale musi to być tablica. – mseancole

+0

Ach, masz to w edytorze ... Czy pętla jest "lepsza" niż ta, którą obecnie robię? Myślę, że zrobienie tego bez pętli byłoby szybsze. – mseancole

+0

@showerhead: Nie wiem, czy jest lepiej, ale zawsze nauczyłem się nie czytać bezpośrednio właściwości @ atrybutów. –

0

myślę, że będzie trzeba pętli. Możesz go dostać do tablicy po przeczytaniu 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

Co to jest "objectsIntoArray"? Nie powinieneś też bezpośrednio czytać atrybutu "atrybuty", do czego służy funkcja '-> attributes()'. –

+0

Przepraszam, wkleiłem z mojego kodu brakującą górną część właśnie go edytowałem. – PoX

40

bardziej elegancki sposób; to daje takie same wyniki bez użycia $ atrybuty [ ''] @attributes:

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

Absolutnie proste, kompaktowe i mniej operacji. –

+0

@silverskater: bardzo przydatne, to działa dla mnie! Wielkie dzięki –

+0

To powinna być odpowiedź – kfriend

Powiązane problemy