Php simplexml change attribute value

Use this corrected....

Show
class ExSimpleXMLElement extends SimpleXMLElement
{    
   function setAttribute(ExSimpleXMLElement $node, $attributeName, $attributeValue, $replace=true)
   {
        $attributes = $node->attributes();

        if (isset($attributes[$attributeName])) {
          if(!empty($attributeValue)){
            if($replace){
                $attributes->$attributeName = (string)$attributeValue;
            } else {
                $attributes->$attributeName = (string)$attributes->$attributeName.(string)$attributeValue;
            }
          } else {
            unset($attributes->$attributeName);
          }
        } else {
          $node->addAttribute($attributeName, $attributeValue);
        }
    }
}

Exemple :


        
    
  XML;

  $xml1 = simplexml_load_string($xml_string, 'ExSimpleXMLElement');
  $xml1->setAttribute($xml1, 'id', 'bar');
  echo $xml1->asXML();

  $xml2 = simplexml_load_string($xml_string, 'ExSimpleXMLElement');
  $xml2->setAttribute($xml2->item, 'id', 'bar');
  echo $xml2->asXML();

  $xml3 = simplexml_load_string($xml_string, 'ExSimpleXMLElement');
  $xml3->setAttribute($xml3->item, 'id', 'bar', false);
  echo $xml3->asXML();

  $xml4 = simplexml_load_string($xml_string, 'ExSimpleXMLElement');
  $xml4->setAttribute($xml4->item, 'id', NULL);
  echo $xml4->asXML();
?>

result:



    




     




      




      

(PHP 5, PHP 7, PHP 8)

SimpleXMLElement::attributesIdentifies an element's attributes

Description

public SimpleXMLElement::attributes(?string $namespaceOrPrefix = null, bool $isPrefix = false): ?SimpleXMLElement

Note: SimpleXML has made a rule of adding iterative properties to most methods. They cannot be viewed using var_dump() or anything else which can examine objects.

Parameters

namespaceOrPrefix

An optional namespace for the retrieved attributes

isPrefix

Default to false

Return Values

Returns a SimpleXMLElement object that can be iterated over to loop through the attributes on the tag.

Returns null if called on a SimpleXMLElement object that already represents an attribute and not a tag.

Examples

Example #1 Interpret an XML string

$string = <<
 1

XML;$xml simplexml_load_string($string);
foreach(
$xml->foo[0]->attributes() as $a => $b) {
    echo 
$a,'="',$b,"\"\n";
}
?>

The above example will output:

Xeoncross

12 years ago

It is really simple to access attributes using array form. However, you must convert them to strings or ints if you plan on passing the values to functions.

SimpleXMLElement Object
(
    [@
attributes] => Array
        (
            [
id] => 55555
       
)

    [

text] => "hello world"
)
?>

Then using a function

function xml_attribute($object, $attribute)
{
    if(isset(
$object[$attribute]))
        return (string)
$object[$attribute];
}
?>

I can get the "id" like this

print xml_attribute($xml, 'id'); //prints "55555"
?>

chris at chlab dot ch

10 years ago

Note that you must provide the namespace if you want to access an attribute of a non-default namespace:

Consider the following example:

$xml = <<
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">




XML;$sxml = new SimpleXMLElement($xml);/**
* Access attribute of default namespace
*/
var_dump((string) $sxml->Table[0]['Foo']);
// outputs: 'Bar'

/**
* Access attribute of non-default namespace
*/

var_dump((int) $sxml->Table[0]['ExpandedColumnCount']);
// outputs: 0var_dump((int) $sxml->Table[0]->attributes('ss', TRUE)->ExpandedColumnCount);
// outputs: '7'
?>

sarlak

11 years ago

$att = 'attribueName';// You can access an element's attribute just like this :
$attribute = $element->attributes()->$att;// This will save the value of the attribute, and not the objet
$attribute = (string)$element->attributes()->$att;// You also can edit it this way :
$element->attributes()->$att = 'New value of the attribute';
?>

totalwipeout at gmail dot com

9 years ago

Tip to get a real array of all attributes of a node (not SimpleXML's object acting like an array)

//- $node is a SimpleXMLElement object$atts_object = $node->attributes(); //- get all attributes, this is not a real array
$atts_array = (array) $atts_object; //- typecast to an array

//- grab the value of '@attributes' key, which contains the array your after

$atts_array = $atts_array['@attributes'];var_dump($atts_object); //- outputs object(SimpleXMLElement)[19]
                        //-             public '@attributes' => ...
var_dump($atts_array); //- outputs array (size=11) ...?>
Hope this helps!

webfelipemaia at gmail dot com

9 years ago

Use attributes to display when it meets certain condition defined attribute / value in xml tags.

Use atributos para exibir quando atende determinada condição definida atributo / valor em tags XML.

Consider the following example:
Considere o seguinte exemplo:

(file.xml)


   
        PHP
        www.php.net
   

   
        Java
        www.oracle.com/br/technologies/java/‎
   

Checks if the attribute value equals "Language", if equal prints everything that is related to "Language".

Verifica se o valor do atributo é igual a "Language", se for, imprime tudo o que for relativo ao mesmo.

$xml

= simplexml_load_file("file.xml");

foreach(

$xml->children() as $child) {$role = $child->attributes();

        foreach(

$child as $key => $value) {

                        if(

$role == "Language")
            echo(
"[".$key ."] ".$value . "
"
);

                    }
}

?>

output:
saída:

[name] PHP
[link] www.php.net

leap

11 years ago

If you want to save the value of an attribute into an array, typecast it to a string.

// stores an xml-element-object
$dataStore['value'] = $attributes->myValue // stores the value of the attribute
$dataStore['value'] = (string)$attributes->myValue
?>

alan at performantsystems dot com

12 years ago

So lets say you have database type data in an XML string called $xmlstring with the key or item ID as an XML Attribute and all content data as regular XML Elements, as above. SimpleXML processes the Attributes as an array, so we can play along and push the Attributes into an array. Then we can get the value of any specific Attribute we want by addressing it by name, such as "ID".

Considering this data:



  
      Navarro Corp.
  

  
      Performant Systems
  

  
      Digital Showcase
  

Example of listing both the ID Attribute and Company Element values:

$xmlObject = new SimpleXMLElement($xmlstring);
foreach (
$xmlObject->children() as $node) {
       
$arr = $node->attributes();   // returns an array
       
print ("ID=".$arr["ID"]);     // get the value of this attribute
       
print ("  Company=".$node->Company);
        print (
"


");
}
?>

skerr at mojavi dot org

17 years ago

You can also access the node as an array to get attributes:

$xml

= simplexml_load_file('file.xml');

echo

'Attribute: ' . $xml['attribute']; ?>

jurchiks101 at gmail dot com

4 years ago

An undocumented way - and, IMO, a hack - of getting an element's value OR attributes
(but not both) without type-casting is to use the function `current()`:

$xml = new SimpleXMLElement(<<<'XML'

    1
   
    3

XML
);
var_dump([
   
'bar' => [
       
$xml->bar,
       
current($xml->bar),
    ],
   
'baz' => [
       
$xml->baz->attributes(),
       
current($xml->baz->attributes()),
    ],
   
'qux' => [
       
// won't work here correctly
       
$xml->qux,
       
current($xml->qux),
       
$xml->qux->attributes(),
       
current($xml->qux->attributes()),
    ],
]);
?>

Results in the following output (re-formatted to shorten it):
```
array(3) {
  'bar' => array(2) {
    [0] => class SimpleXMLElement#2 (1) {
      public ${0} => string(1) "1"
    }
    [1] => string(1) "1"
  }
  'baz' => array(2) {
    [0] => class SimpleXMLElement#5 (1) {
      public $@attributes => array(1) {
        ...
      }
    }
    [1] => array(1) {
      'name' => string(3) "baz"
    }
  }
  'qux' => array(4) {
    [0] => class SimpleXMLElement#6 (2) {
      public $@attributes => array(1) {
        ...
      }
      public ${0} => string(1) "3"
    }
    [1] => array(1) {
      'name' => string(3) "qux"
    }
    [2] => class SimpleXMLElement#7 (1) {
      public $@attributes => array(1) {
        ...
      }
    }
    [3] => array(1) {
      'name' => string(3) "qux"
    }
  }
}
```

This apparently reads the element as an array and just returns the value of the first property, whether it be the attributes or the value. As seen in the third example, this is unreliable, especially if you're parsing XML from an outside source that may or may not have attributes on an element that you want the value of.

I certainly do NOT advise anyone to use this since it is undocumented and it is just a coincidence that it works, so it might break in the future without prior notice.

zevnikrok

7 years ago

If you wish to get attributes as an associative array of key value pairs, you don't need to iterate through them, you can get it with this one liner:

  reset($element->attributes())

adrian at foeder dot de

9 years ago

in order to get a possibly present xml:space attribute, use the following construct:

$simpleXmlElement->element->attributes('http://www.w3.org/XML/1998/namespace')->space;
?>

This will, for example, return 'preserve' if set.

Just passing by 'xml' as namespace argument of the attribute() method didn't work out for me. Passing by the complete namespace URI works also if it is not explicitly defined in the underlying XML document.

Also, $simpleXmlElement->getNamespaces() does not return anything of use.

inge at elektronaut dot no

18 years ago

here's a simple function to get an attribute by name, based on the example

function findAttribute($object, $attribute) {
  foreach(
$object->attributes() as $a => $b) {
    if (
$a == $attribute) {
     
$return = $b;
    }
  }
  if(
$return) {
    return
$return;
  }
}
?>