Доступ к @attribute из SimpleXML

120

У меня проблема с доступом к @attributeразделу моего объекта SimpleXML. Когда я var_dumpобрабатываю весь объект, я получаю правильный результат, а когда я var_dumpостальной объект (вложенные теги), я получаю правильный результат, но когда я следую документам и var_dump $xml->OFFICE->{'@attributes'}, я получаю пустой объект, несмотря на то, что первый var_dumpясно показывает, что есть атрибуты для вывода.

Кто-нибудь знает, что я здесь делаю неправильно / как я могу заставить эту работу?

Бенджи
источник
5
var_dump () вводит в заблуждение, когда дело доходит до SimpleXML. Не воспринимайте результат буквально. Кроме того, вы не можете получить доступ к атрибутам, используя доступ к массиву? например, $ xml-> OFFICE ['MyAttribute']?
Фрэнк Фармер,
если вы хотите использовать ['@attributes'], вам нужно сначала преобразовать SimpleXMLElement в массив
Энрике

Ответы:

88

Вы можете получить атрибуты элемента XML, вызвав функцию attributes () на узле XML. Затем вы можете var_dump возвращаемое значение функции.

Дополнительная информация на php.net http://php.net/simplexmlelement.attributes

Пример кода с этой страницы:

$xml = simplexml_load_string($string);
foreach($xml->foo[0]->attributes() as $a => $b) {
    echo $a,'="',$b,"\"\n";
}
Нильс Бом
источник
7
Интересно, $bчто SimpleXMLElementобъект будет таким print_rи var_dumpдаст вам странные вещи. Вы можете преобразовать его как строку (или что угодно), чтобы обойти это.
jxmallett
Сделайте "". $ B, чтобы сохранить его как строку
dr_rk 03
135

Попробуй это

$xml->attributes()->Token
zysoft
источник
2
@Artefacto уже ответил на этот вопрос .
hakre
45
Да, но в более жесткой форме
zysoft
2
Ага, это самое элегантное решение.
Christian
Я пробовал это и думаю, что страница вылетает. Бора ниже, кажется, думает, что это неправильный формат, с которым я согласен в данный момент ... Однако я видел этот (ваш) формат, упомянутый несколько раз. Есть какой-то нюанс, который мне не хватает?
Gerard ONeill
2
@GerardONeill, я не понимаю, почему Бора говорит, что это неправильный способ доступа к атрибутам, он работает довольно идеально. Возможно, вам не хватает того, что вам нужно вызвать attributes()объект, соответствующий правильному тегу в вашем XML. Например, если у вас есть, <root><tag attr="a">b</tag></root>то вам нужно сделать $xml->tag->attributes()->attrдля доступа к нему.
zysoft
55

Раньше я использовал так много раз, @attributesкак показано ниже, и это было немного дольше.

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

Это должно быть проще, и вы можете получить атрибуты следующего формата только сразу:

Стандартный способ - атрибуты доступа к массиву (AAA)

$xml['field'];

Другие альтернативы:

Правое и быстрое форматирование

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

Неправильные форматы

$xml->attributes()->field;
$xml->{"@attributes"}->field;
$xml->attributes('field');
$xml->attributes()['field'];
$xml->attributes->['field'];
бора
источник
1
Я согласен с вашим первым неправильным форматом, потому что у меня вылетает страница, однако несколько человек утверждают, что это работает. Есть какие-нибудь объяснения или нюансы по этому поводу?
Gerard ONeill
1
"Неправильные форматы" работают. Я всегда использую первый пример. Почему это неправильно?
Grzegorz
3
С технической точки зрения $xml->attributes()->{'field'}, $xml->attributes()->fieldи $f='field'; $xml->attributes()->$f;то же самое. Не вижу причин, почему один формат правильный, а другой - нет.
zysoft
$ xml-> attributes () -> {'field'} является правильным, поскольку безопасно использовать специальные символы в имени атрибута (например, "data-attr"). $ xml-> attributes () -> field работает только для атрибутов, которые представляют собой отдельные буквенно-цифровые слова
vzr
Получение SimpleXMLElement при использовании обоих правильных вариантов.
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"]

Используйте SimpleXMLElement::attributes.

По правде говоря, get_propertiesобработчик SimpleXMLElement врет. Нет свойства с именем "@attributes", поэтому вы не можете этого сделать $sxml->elem->{"@attributes"}["attrib"].

Artefacto
источник
Спасибо за объяснение, почему SimpleXML ведет себя таким странным образом ( get_propertiesобработчик). Очень интересно.
andrewtweber 02
Получение SimpleXMLElement при выполнении этого вместо значения
Darius. V
15

Вы можете просто сделать:

echo $xml['token'];
Аликс Аксель
источник
8

Если вы ищете список этих атрибутов, XPath будет вашим другом.

print_r($xml->xpath('@token'));
Кори Кольер
источник
3

Это помогло мне преобразовать результат simplexml_load_file ($ file) в структуру JSON и декодировать его обратно:

$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
источник
2

К сожалению, у меня есть уникальная сборка (на данный момент застрявшая с Gentoo) PHP 5.5, и я обнаружил, что

 $xml->tagName['attribute']

было единственным решением, которое сработало. Я пробовал все методы Бора, описанные выше, включая формат «Правильный и быстрый», и все они потерпели неудачу.

Тот факт, что это самый простой формат, является плюсом, но мне не нравилось думать, что я сошел с ума, пробуя все форматы, которые, по словам других, работали.

Njoy, какой он стоит (я уже говорил об уникальной сборке?).

Джерард Онейл
источник
Обычно я бы рекомендовал использовать нотацию массива для атрибутов для атрибутов в том же пространстве имен элемента, в который они входят. Я бы сказал, что это самый простой формат (как вы его называете) не зря. доступ к массиву с именованным атрибутом key = с элементом simplexml.
hakre