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?


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";
}

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

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'];

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"].


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


8

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

print_r($xml->xpath('@token'));

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
)

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


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.