Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : SimpleXML functions : SimpleXMLElement->attributes()

SimpleXMLElement->attributes()

Identifies an element's attributes ()

SimpleXMLElement {
  SimpleXMLElement attributes(string ns,
                              bool is_prefix);

}

This function provides the attributes and values defined within an xml tag.

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

ns

An optional namespace for the retrieved attributes

is_prefix

Default to FALSE

Return Values

Examples

Example 2251. Interpret an XML string

<?php
$string
= <<<XML
<a xmlns:b>
<foo name="one" game="lonely">1</foo>
</a>
XML;

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

The above example will output:

name="one"
game="lonely"


Related Examples ( Source code ) » simplexml element attributes










Code Examples / Notes » simplexml element attributes

skerr

You can also access the node as an array to get attributes:
<?php
$xml = simplexml_load_file('file.xml');
echo 'Attribute: ' . $xml['attribute'];
?>


tychay

Why bother iterating over all the elements when they are already indexed? something like...
function simplexml_find_attribute(SimpleXMLElement $element, $attributeName) {
   $attrs = $element->attributes();
   if (isset($attrs[$attributeName])) {
       return (string) $attrs[$attributeName];
   }
   return false;
}
- terry


christian

PHP5:: I think this is a fine solution to get the attributes easier...
<?php
class EFXMLElement extends SimpleXMLElement {
function attributes() {
  return new EFXMLAttributes(parent::attributes());
}
}
class EFXMLAttributes {
private $attributes;
function __construct($attributes) {
$this->attributes = $attributes;
}
function __get($name) {
if (isset($this->attributes[$name])) {
return $this->attributes[$name];
} else {
return false;
}
}
}
if (file_exists('pref.xml')) {
$tst = new EFXMLElement(file_get_contents('pref.xml'));
var_dump($tst->plugins->plugin[0]->attributes()->name);
} else {
   exit('Failed to open test.xml.');
}
?>
XML::example
<?xml version="1.0" encoding="ISO8859-1" ?>
<preferences>
<system>
EF3
</system>
<websites>
<website name="demo">
<scriptpath>/</scriptpath>
</website>
<website name="other">
x
</website>
</websites>
<plugins>
<plugin type="single" name="content" ontemplate="yes">
<tag><![CDATA[<%content%>]]></tag>
<class>EFContentPlugin</class>
<source>/ef3/plugins/EFContentPlugin.class</source>
</plugin>
<plugin type="single" name="attribute" ontemplate="no">
<tag><![CDATA[<%attribute @%>]]></tag>
<class>EFAttributePlugin</class>
<source>/ef3/plugins/EFAttributePlugin.class</source>
</plugin>
<plugin type="single" name="component" ontemplate="no">
<tag><![CDATA[<%component @%>]]></tag>
<class>EFComponentPlugin</class>
<source>/ef3/plugins/EFComponentPlugin.class</source>
</plugin>
<plugin type="double" name="klammer" ontemplate="no">
<tag><![CDATA[<KLAMMER@>]]></tag>
<closer><![CDATA[<KLAMMER@>]]></closer>
<class>KlammerPlugin</class>
<source>/ef3/plugins/KlammerPlugin.class</source>
</plugin>
</plugins>
</preferences>


sveta

Namespace handling example:
------------------------------------
test.xml:
<?xml version="1.0"?>
<Workbook xmlns="http://url1" xmlns:ss="http://url2">
<Worksheet ss:Name="English">
</Worksheet>
</Workbook>
script.php:
$xml_file = 'test.xml';
$xml = simplexml_load_file($xml_file);
foreach($xml->Worksheet->attributes('http://url2')
as $a => $b) {
   echo $a,'="',$b,"\"\n";
}


matt

It is worth mentioning that if you try to check for attributes when none exists, the PHP compiler just crashes.
So you either need to check for the tag and do a preg_match for attributes or some other sort of check before you use this function.


eirik sletteberg

In reply to inge at elektronaut dot no's function:
Notice that this function returns an object, and not
a string. This is quite hard to notice at first, because
if you validate the return against a string, it will return
true:
print findAttribute($Fox, "foo") == "bar"? "Matches.":"Won't match."; // "Matches."
But, if you attempt to use the return for indexing in an array, like:
$MyArray[findattribute($Fox, "foo")] = "bar";
You will get an illegal offset type-error.
------
To correct this, we force-cast the return as a string:
function findAttribute($object, $attribute) {
 foreach($object->attributes() as $a => $b) {
  if ($a == $attribute) {
    $return = $b;
  }
 }
 if($return) {
  return (string)$return;
 }
}


studio

I expanded a bit (not very impressive, I admit) on the user submitted class for extending simple xml.  
Below are some nice quick and dirty additional class functions I have needed to manage the back end for plugging in flash parameters to dynamic actionscripted .swf files needing this xml data generated dynamically and with working variable xml content data that the client maintains (yikes!).  Probably need some bad character checking in here somewhere?
<?php
$xml_data = '<?xml version="1.0" encoding="ISO8859-1" ?>
<root>
<image name="Banner 1" file="pic1.jpg" />
<image name="Banner 2" file="pic2.jpg" />
<image name="Banner 3" file="pic3.jpg" />
<image name="Banner 4" file="pic4.jpg" />
</root>';
class SimpleXMLElementExtended extends SimpleXMLElement{

public function getAttribute($name){
foreach($this->attributes() as $key=>$val){
if($key == $name){
return (string)$val;
}// end if
}// end foreach
}// end function getAttribute

public function getAttributeNames(){
$cnt = 0;
$arrTemp = array();
foreach($this->attributes() as $a => $b) {
$arrTemp[$cnt] = (string)$a;
$cnt++;
}// end foreach
return (array)$arrTemp;
}// end function getAttributeNames

public function getChildrenCount(){
$cnt = 0;
foreach($this->children() as $node){
$cnt++;
}// end foreach
return (int)$cnt;
}// end function getChildrenCount

public function getAttributeCount(){
$cnt = 0;
foreach($this->attributes() as $key=>$val){
$cnt++;
}// end foreach
return (int)$cnt;
}// end function getAttributeCount

public function getAttributesArray($names){
$len = count($names);
$arrTemp = array();
for($i = 0; $i < $len; $i++){
$arrTemp[$names[$i]] = $this->getAttribute((string)$names[$i]);
}// end for
return (array)$arrTemp;
}// end function getAttributesArray

}
$xml2 = new SimpleXMLElementExtended($xml_data);

print('<pre>');
print('NUMBER OF CHILDREN:  '.$xml2->getChildrenCount());
print('</pre>');

print('<pre>');
print('ATTRIBUTE COUNT PER CHILD:  '.$xml2->image[0]->getAttributeCount());
print('</pre>');

print('<pre>');
print('CHILD 0 ATTRIBUTE "name":  '.$xml2->image[0]->getAttribute('name'));
print('</pre>');

print('<pre>');
print('CHILD 0 ATTRIBUTE "file":  '.$xml2->image[0]->getAttribute('file'));
print('</pre>');

$arrTemp = array('name', 'file');
$arrResult = array();
$arrResult = $xml2->image[0]->getAttributesArray($arrTemp);
print('<pre>');
print('CHILD 0 ATTRIBUTE ARRAY:  "name,file":
');
print(var_dump($arrResult));
print('</pre>');

$arrResult = array();
$arrResult = $xml2->image[0]->getAttributeNames();
print('<pre>');
print('CHILD 0 ATTRIBUTE NAMES ARRAY:
');
print(var_dump($arrResult));
print('</pre>');

print('<hr>');

$arrCompiled = array();
$arrCompiled = $xml2->image[0]->getAttributesArray($arrResult);
print('<pre>');
print('CHILD 0 DYNAMIC COMPILED ATTRIBUTE ARRAY:  "key,value"
');
print(var_dump($arrCompiled));
print('</pre>');
?>
Outputs something along these lines below:
NUMBER OF CHILDREN:  4
ATTRIBUTE COUNT PER CHILD:  2
CHILD 0 ATTRIBUTE "name":  Banner 1
CHILD 0 ATTRIBUTE "file":  pic1.jpg
CHILD 0 ATTRIBUTE ARRAY:  "name,file":
array(2) {
 ["name"]=>
 string(8) "Banner 1"
 ["file"]=>
 string(8) "pic1.jpg"
}
CHILD 0 ATTRIBUTE NAMES ARRAY:
array(2) {
 [0]=>
 string(4) "name"
 [1]=>
 string(4) "file"
}
CHILD 0 DYNAMIC COMPILED ATTRIBUTE ARRAY:  "key,value"
array(2) {
 ["name"]=>
 string(8) "Banner 1"
 ["file"]=>
 string(8) "pic1.jpg"
}
I'm sure there is more to add/revise/simplify, but it's a fast start to working with fairly simple xml schema/structures.
Would be interested is anyone knows of how we could revise this class to say perhaps evaluate the nodes AND attributes for the same xml element... like image id attribute with say 4 image file name elements?
Peace.


inge

here's a simple function to get an attribute by name, based on the example
<?php
function findAttribute($object, $attribute) {
 foreach($object->attributes() as $a => $b) {
   if ($a == $attribute) {
     $return = $b;
   }
 }
 if($return) {
   return $return;
 }
}
?>


tychay

BTW, It occurs to me that why do you need the function anyway? You just access it directly as (string) $object[$attribute].

Change Language


Follow Navioo On Twitter
SimpleXMLElement->addAttribute()
SimpleXMLElement->addChild()
SimpleXMLElement->asXML()
SimpleXMLElement->attributes()
SimpleXMLElement->children()
SimpleXMLElement->__construct()
SimpleXMLElement->getDocNamespaces()
SimpleXMLElement->getName()
SimpleXMLElement->getNamespaces()
SimpleXMLElement->registerXPathNamespace()
SimpleXMLElement->xpath()
simplexml_import_dom
simplexml_load_file
simplexml_load_string
eXTReMe Tracker