SimpleXMLElement::addAttribute
(PHP 5 >= 5.1.3, PHP 7)
SimpleXMLElement::addAttribute — Добавляет атрибут к SimpleXML-элементу
Описание
$name
[, string $value
[, string $namespace
]] )Добавляет атрибут к SimpleXML-элементу.
Список параметров
-
name
-
Название добавляемого атрибута.
-
value
-
Значение атрибута.
-
namespace
-
Необязательный параметр указывает на пространство имен, к которому принадлежит атрибут.
Возвращаемые значения
Эта функция не возвращает значения после выполнения.
Примеры
Замечание:
Перечисленные примеры могут включать example.php, в котором определяется XML-строка, расположенная в первом примере руководства по базовому использованию.
Пример #1 Добавление атрибутов и потомков к SimpleXML-элементу
<?php
include 'example.php';
$sxe = new SimpleXMLElement($xmlstr);
$sxe->addAttribute('type', 'documentary');
$movie = $sxe->addChild('movie');
$movie->addChild('title', 'PHP2: Истории парсера');
$movie->addChild('plot', 'Все о людях, создававших его.');
$characters = $movie->addChild('characters');
$character = $characters->addChild('character');
$character->addChild('name', 'Mr. Parser');
$character->addChild('actor', 'John Doe');
$rating = $movie->addChild('rating', '5');
$rating->addAttribute('type', 'stars');
echo $sxe->asXML();
?>
Результатом выполнения данного примера будет что-то подобное:
<?xml version="1.0" standalone="yes"?> <movies type="documentary"> <movie> <title>PHP: Появление Парсера</title> <characters> <character> <name>Ms. Coder</name> <actor>Onlivia Actora</actor> </character> <character> <name>Mr. Coder</name> <actor>El ActÓr</actor> </character> </characters> <plot> Итак, этот язык. Типа, язык программирования. Или это скриптовый язык? Все раскрывается в этом документальном фильме, похожем на фильм ужасов. </plot> <great-lines> <line>PHP решает все мои задачи в web</line> </great-lines> <rating type="thumbs">7</rating> <rating type="stars">5</rating> </movie> <movie> <title>PHP2: Истории парсера</title> <plot>Все о людях, создававших его.</plot> <characters> <character> <name>Mr. Parser</name> <actor>John Doe</actor> </character> </characters> <rating type="stars">5</rating> </movie> </movies>
Смотрите также
- SimpleXMLElement::addChild() - Добавляет дочерний элемент к узлу XML
- Базовое использование SimpleXML
- Функция SimpleXMLElement::addAttribute() - Добавляет атрибут к SimpleXML-элементу
- Функция SimpleXMLElement::addChild() - Добавляет дочерний элемент к узлу XML
- Функция SimpleXMLElement::asXML() - Возвращает сформированный XML документ в виде строки используя SimpleXML элемент
- Функция SimpleXMLElement::attributes() - Возвращает атрибуты элемента
- Функция SimpleXMLElement::children() - Поиск дочерних элементов данного узла
- Функция SimpleXMLElement::__construct() - Создание нового SimpleXMLElement объекта
- Функция SimpleXMLElement::count() - Считает количество дочерних элементов у текущего элемента
- Функция SimpleXMLElement::getDocNamespaces() - Возвращает объявленное пространство имен в документе
- Функция SimpleXMLElement::getName() - Получение имени XML элемента
- Функция SimpleXMLElement::getNamespaces() - Получение пространств имен, используемых в документе
- Функция SimpleXMLElement::registerXPathNamespace() - Создает префикс/пространство имен контекста для следующего XPath запроса
- Функция SimpleXMLElement::saveXML() - Псевдоним SimpleXMLElement::asXML
- Функция SimpleXMLElement::__toString() - Returns the string content
- Функция SimpleXMLElement::xpath() - Запускает XPath запрос к XML данным
Коментарии
If the attribute already exists, addAttribute does nothing.
example:
<?php
$xml_string = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<root>
<item id="foo">
<root>
XML;
$xml = simplexml_load_string($xml_string);
$xml->item->addAttribute('id', 'bar');
echo $xml->asXML();
?>
The above examples will output:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<item id="foo">
<root>
You can access a node child with his name this way :
<?php
$root = new SimpleXMLElement($filePath);
echo $root->nodeName->attributes;
// It works recursivly so this will work too
echo $root->nodeName->subNodeName->attributes();
?>
But if you want to ADD an attribute to a children you MUST use the children() method to access and modfiy it or it will modify the parent's attributes.
<?php
// Add a subnode
$element->nodeName->addChild('subNodeName', "whatever you want");
// Get the pos in the childrens of the parent node
$lastNodePos = $element->nodeName->count()-1;
// Get the parents node childrens
$nodeChildrens = $element->nodeName->children();
// Add an attribute to the last created
$nodeChildrens[$lastNodePos]->addAttribute('attributeName', "The attribute value);
?>
If you need an Namespace, you must write a Prefix of the Namespace + the Name of the Attribute ("prefix:name") as the first parameter AND the uri as the third one. (I don't know why?!)
Example code:
<?php
$xml = new SimpleXMLElement("<packagedElement></packagedElement>");
$xml->addAttribute("xmi:type", "uml:Class", "http://schema.omg.org/spec/XMI/2.1");
echo $xml->asXml();
?>
Output:
<packagedElement xmlns:xmi="http://schema.omg.org/spec/XMI/2.1" xmi:type="uml:Class"></packagedElement>
You cannot use this to update an existing attribute's value.
Instead, get a DOM version of the SimpleXMLElement and use setAttribute, as per:
$XML = '<element a="aa">Text</element>';
$snode = new simple_xml_element($XML);
$dnode = dom_import_simplexml($snode);
$dnode->setAttribute('a', 'bb');
Resulting XML for the node is:
<element a="bb">Text</element>
I needed a way to update an attribute, but I could not find any documented way to do this.
TL;DR: It's not only possible, but unbelievably simple. See the other note I submitted for what actually works (sorry, I could not fit it all in a single note due to the 4095 character limit).
After much experimentation, here's my findings of what does NOT work; hopefully, it saves you the time and frustration it cost me.
Given the following example:
<?php
$xml = <<<EOF
<?xml version="1.0" encoding="utf-8" ?>
<Animals>
<Dog/>
</Animals>
EOF;
$animals = new SimpleXMLElement($xml);
echo $animals->Dog->asXML();
// <Dog/>
?>
Test #1 - attempt to call addAttribute() twice
TL;DR: PHP Warning: SimpleXMLElement::addAttribute(): Attribute already exists
<?php
...
$animals->Dog->addAttribute('breed', "chihuahua");
echo $animals->Dog->asXML();
// <Dog breed="chihuahua"/>
$animals->Dog->addAttribute('breed', "poodle");
// PHP Warning: SimpleXMLElement::addAttribute(): Attribute already exists
echo $animals->Dog->asXML();
// <Dog breed="chihuahua"/>
?>
Test #2 - attempt to iterate attributes() (an Iterator) by reference
TL;DR: An iterator cannot be used with foreach by reference
<?php
...
$animals->Dog->addAttribute('breed', "chihuahua");
echo $animals->Dog->asXML();
// <Dog breed="chihuahua">
try {
foreach ($animals->Dog->attributes() as $attr => &$value) {
if ("breed" === $attr) {
$value = "poodle";
}
}
} catch (Throwable $e) {
echo $e->getMessage();
// An iterator cannot be used with foreach by reference
}
echo $animals->Dog->asXML();
// <Dog breed="chihuahua">
?>
Test #3 - attempt to re-parse child element and then call addAttribute() on the newly parsed element, as suggested in a note I found here
TL;DR: PHP Warning: SimpleXMLElement::addAttribute(): Attribute already exists
<?php
...
$animals->Dog->addAttribute('breed', "chihuahua");
echo $animals->Dog->asXML();
// <Dog breed="chihuahua">
$animals->Dog = new SimpleXMLElement($animals->asXML());
$animals->Dog->addAttribute('breed', "poodle");
// PHP Warning: SimpleXMLElement::addAttribute(): Attribute already exists
echo $animals->Dog->asXML();
// <Dog breed="chihuahua">
?>
Test #4 - attempt to modify @attributes array element
TL;DR: PHP Notice: Indirect modification of overloaded element of SimpleXMLElement has no effect
<?php
...
$animals->Dog->addAttribute('breed', "chihuahua");
echo $animals->Dog->asXML();
// <Dog breed="chihuahua">
$dogAttrs = $animals->Dog->attributes();
// object(SimpleXMLElement)#4 (1) {
// ["@attributes"]=>
// array(1) {
// ["breed"]=>
// string(9) "chihuahua"
// }
// }
$dogAttrs['@attributes']['breed'] = "poodle";
// PHP Notice: Indirect modification of overloaded element of SimpleXMLElement has no effect
echo $animals->Dog->asXML();
// <Dog breed="chihuahua">
?>
Test #5 - cast attributes() to array and set value of 'breed' element
TL;DR: does not update value in original object
<?php
...
$animals->Dog->addAttribute('breed', "chihuahua");
echo $animals->Dog->asXML();
// <Dog breed="chihuahua">
$dogAttrs = (array) $animals->Dog->attributes();
// array(1) {
// ["@attributes"]=>
// array(1) {
// ["breed"]=>
// string(9) "chihuahua"
// }
// }
$dogAttrs['@attributes']['breed'] = "poodle";
echo $animals->Dog->asXML();
// <Dog breed="chihuahua">
?>
I needed a way to update an attribute, but I could not find any documented way to do this.
After much experimentation, here's my findings of what works - the answer was so simple it took me 8 tries to figure it out :-)
Given the following example:
<?php
$xml = <<<EOF
<?xml version="1.0" encoding="utf-8" ?>
<Animals>
<Dog/>
</Animals>
EOF;
$animals = new SimpleXMLElement($xml);
echo $animals->Dog->asXML();
// <Dog/>
?>
Test #6 - maybe directly modifying the attributes() Iterator like an array will secretly call __set() magic method?
TL;DR: yep
<?php
...
$animals->Dog->addAttribute('breed', "chihuahua");
echo $animals->Dog->asXML();
// <Dog breed="chihuahua">
$dogAttrs = $animals->Dog->attributes();
// object(SimpleXMLElement)#4 (1) {
// ["@attributes"]=>
// array(1) {
// ["breed"]=>
// string(9) "chihuahua"
// }
// }
$dogAttrs['breed'] = "poodle";
// works!
echo $animals->Dog->asXML();
// <Dog breed="poodle">
?>
Test #7 - maybe I don't even need to call attributes() at all?
TL;DR: I sure don't!
<?php
...
$animals->Dog->addAttribute('breed', "chihuahua");
echo $animals->Dog->asXML();
// <Dog breed="chihuahua">
$animals->Dog['breed'] = "poodle";
// works!
echo $animals->Dog->asXML();
// <Dog breed="poodle">
?>
Test #8 - Maybe I never needed to call addAttribute() in the first place?
TL;DR: nope, I can skip that altogether!
<?php
...
$animals->Dog['breed'] = "chihuahua";
// works!
echo $animals->Dog->asXML();
// <Dog breed="chihuahua">
$animals->Dog['breed'] = "poodle";
// works!
echo $animals->Dog->asXML();
// <Dog breed="poodle">
?>
FYI: I also submitted another separate note with what does NOT work just in case you, like me, are curious and tempted to try another way.
Just found another gem. Need to remove an attribute? That's simple too!
<?php
$xml = <<<EOF
<?xml version="1.0" encoding="utf-8" ?>
<Animals>
<Dog breed="chihuahua"/>
</Animals>
EOF;
$animals = new SimpleXMLElement($xml);
echo $animals->Dog->asXML();
// <Dog breed="chihuahua"/>
unset($animals->Dog['breed']);
echo $animals->Dog->asXML();
// <Dog/>
?>