SimpleXMLElement::addAttribute

(PHP 5 >= 5.1.3, PHP 7, PHP 8)

SimpleXMLElement::addAttribute Adds an attribute to the SimpleXML element

Description

public SimpleXMLElement::addAttribute(string $qualifiedName, string $value, ?string $namespace = null): void

Adds an attribute to the SimpleXML element.

Parameters

qualifiedName

The name of the attribute to add.

value

The value of the attribute.

namespace

If specified, the namespace to which the attribute belongs.

Return Values

No value is returned.

Examples

Note:

Listed examples may include example.php, which refers to the XML string found in the first example of the basic usage guide.

Example #1 Add attributes and children to a SimpleXML element

<?php

include 'example.php';

$sxe = new SimpleXMLElement($xmlstr);
$sxe->addAttribute('type', 'documentary');

$movie = $sxe->addChild('movie');
$movie->addChild('title', 'PHP2: More Parser Stories');
$movie->addChild('plot', 'This is all about the people who make it work.');

$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();

?>

The above example will output something similar to:

<?xml version="1.0" standalone="yes"?>
<movies type="documentary">
 <movie>
  <title>PHP: Behind the Parser</title>
  <characters>
   <character>
    <name>Ms. Coder</name>
    <actor>Onlivia Actora</actor>
   </character>
   <character>
    <name>Mr. Coder</name>
    <actor>El Act&#xD3;r</actor>
   </character>
  </characters>
  <plot>
   So, this language. It's like, a programming language. Or is it a
   scripting language? All is revealed in this thrilling horror spoof
   of a documentary.
  </plot>
  <great-lines>
   <line>PHP solves all my web problems</line>
  </great-lines>
  <rating type="thumbs">7</rating>
  <rating type="stars">5</rating>
 </movie>
 <movie>
  <title>PHP2: More Parser Stories</title>
  <plot>This is all about the people who make it work.</plot>
  <characters>
   <character>
    <name>Mr. Parser</name>
    <actor>John Doe</actor>
   </character>
  </characters>
  <rating type="stars">5</rating>
 </movie>
</movies>

See Also

add a note

User Contributed Notes 7 notes

up
4
Patanjali
8 years ago
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>
up
3
booleer at yahoo dot it
14 years ago
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>
up
2
caffeinatedbits
2 years ago
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/>

?>
up
2
caffeinatedbits
2 years ago
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.
up
1
p.servus
13 years ago
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>
up
0
caffeinatedbits
2 years ago
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">

?>
up
0
sarlak
13 years ago
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);
?>
To Top