Acessando @attribute de SimpleXML

120

Estou tendo problemas para acessar a @attributeseção do meu objeto SimpleXML. Quando eu var_dumpobtenho o objeto inteiro, obtenho a saída correta, e quando obtenho o var_dumpresto do objeto (as tags aninhadas), obtenho a saída correta, mas quando sigo os documentos e var_dump $xml->OFFICE->{'@attributes'}, obtenho um objeto vazio, apesar do fato de que o primeiro var_dumpmostra claramente que existem atributos para a saída.

Alguém sabe o que estou fazendo de errado aqui / como posso fazer isso funcionar?

Benjy
fonte
5
var_dump () é enganoso, quando se trata de SimpleXML. Não tome sua saída literalmente. Além disso, você não pode acessar atributos usando o acesso à matriz? por exemplo, $ xml-> OFFICE ['MyAttribute']?
Frank Farmer
se você quiser usar ['@attributes'], você precisa primeiro lançar o SimpleXMLElement para a matriz
Enrique

Respostas:

88

Você pode obter os atributos de um elemento XML chamando a função attribute () em um nó XML. Você pode então var_dump o valor de retorno da função.

Mais informações em php.net http://php.net/simplexmlelement.attributes

Exemplo de código dessa página:

$xml = simplexml_load_string($string);
foreach($xml->foo[0]->attributes() as $a => $b) {
    echo $a,'="',$b,"\"\n";
}
Niels Bom
fonte
7
Curiosamente, $bserá um SimpleXMLElementobjeto assim print_re var_dumplhe dará coisas estranhas. Você pode lançá-lo como uma corda (ou o que quiser) para contornar isso.
jxmallett de
Faça "". $ B para mantê-lo como uma string
dr_rk
135

Tente isto

$xml->attributes()->Token
zysoft
fonte
2
Isso já foi respondido por @Artefacto .
hakre
45
Sim, mas de uma forma mais difícil
zysoft
2
Sim, esta é a solução mais elegante.
Cristão
Tentei fazer isso e acho que a página está travando. O Bora abaixo parece pensar que este é um formato errado, com o qual estou de acordo neste momento. No entanto, já vi este (seu) formato mencionado várias vezes. Existe alguma nuance que estou perdendo?
Gerard ONeill
2
@GerardONeill, Não entendo por que Bora diz que é uma forma errada de acessar os atributos, funciona perfeitamente. O que pode estar faltando é que você precisa chamar attributes()no objeto correspondente a tag certa em seu XML. Como se você tivesse, <root><tag attr="a">b</tag></root>então você precisa fazer $xml->tag->attributes()->attrpara acessá-lo.
zysoft
55

Eu usei tantas vezes antes para ficar @attributescomo embaixo e foi um pouco mais longo.

$att = $xml->attributes();
echo $att['field'];

Deve ser mais fácil e você pode obter atributos seguindo o formato apenas de uma vez:

Forma padrão - Atributos de acesso a matriz (AAA)

$xml['field'];

Outras alternativas são:

Formato correto e rápido

$xml->attributes()->{'field'};

Formatos errados

$xml->attributes()->field;
$xml->{"@attributes"}->field;
$xml->attributes('field');
$xml->attributes()['field'];
$xml->attributes->['field'];
Bora
fonte
1
Estou concordando com seu primeiro dos formatos errados porque estou tendo uma página travada - no entanto, várias pessoas estão alegando que isso funciona. Alguma explicação ou nuance sobre isso?
Gerard ONeill
1
"Formatos errados" funcionam. Eu sempre uso o primeiro exemplo. Por que isso está errado?
Grzegorz
3
Tecnicamente, $xml->attributes()->{'field'}, $xml->attributes()->field, e $f='field'; $xml->attributes()->$f;são os mesmos. Não veja nenhuma razão pela qual um está no formato correto e outro está errado.
zysoft
$ xml-> attribute () -> {'field'} está correto porque é seguro usar com caracteres especiais no nome do atributo (ou seja, "data-attr"). $ xml-> attributes () -> campo funciona apenas para atributos que são palavras alfanuméricas únicas
vzr
Obtendo SimpleXMLElement ao usar as duas opções corretas.
Darius.V
41
$xml = <<<XML
<root>
<elem attrib="value" />
</root>
XML;

$sxml = simplexml_load_string($xml);
$attrs = $sxml->elem->attributes();
echo $attrs["attrib"]; //or just $sxml->elem["attrib"]

Use SimpleXMLElement::attributes.

A verdade é que o get_propertiesmanipulador SimpleXMLElement é um grande momento. Não há propriedade chamada "@attributes", então você não pode fazer isso $sxml->elem->{"@attributes"}["attrib"].

Artefacto
fonte
Obrigado por explicar por que SimpleXML se comporta dessa maneira bizarra (o get_propertiesmanipulador). Muito interessante.
andrewtweber
Obtendo SimpleXMLElement ao fazer isso em vez de valor
Darius.V
15

Você pode apenas fazer:

echo $xml['token'];
Alix Axel
fonte
8

Se você estiver procurando por uma lista desses atributos, XPath será seu amigo

print_r($xml->xpath('@token'));
Cory Collier
fonte
3

Isso me ajudou a converter o resultado de simplexml_load_file ($ file) em uma estrutura JSON e decodificá-lo de volta:

$xml = simplexml_load_file("$token.xml");
$json = json_encode($xml);
$xml_fixed = json_decode($json);

$try1 = $xml->structure->{"@attributes"}['value'];
print_r($try1);

>> result: SimpleXMLElement Object
(
)

$try2 = $xml_fixed->structure->{"@attributes"}['value'];
print_r($try2);

>> result: stdClass Object
(
    [key] => value
)
t2m
fonte
2

Infelizmente eu tenho uma compilação única (presa no Gentoo por enquanto) do PHP 5.5, e o que eu descobri foi que

 $xml->tagName['attribute']

foi a única solução que funcionou. Tentei todos os métodos do Bora acima, incluindo o formato 'Certo e Rápido', e todos falharam.

O fato de este ser o formato mais fácil é uma vantagem, mas não gostei de pensar que estava louco tentando todos os formatos que os outros diziam que funcionavam.

Njoy pelo que vale (eu mencionei construção única?)

Gerard ONeill
fonte
Eu normalmente recomendaria usar notação de array para atributos para os atributos no mesmo namespace do elemento do qual fazem parte. Eu diria que é o formato mais fácil (como você pensa) por um motivo. array-access com um atributo key = nomeado com elemento simplexml.
hakre