It's helpful if you don't think of 'SimpleXML' as 'DOM' because
it's not. SimpleXML is an 'Object Mapping XML API', which means it converts the XML elements into the native data types used by PHP.
So attributes on an 'element' are accessible using standard
array notation:
$simplexml->path->to->descendant['attribute-name']
Dead simple, pun intended ;)
skerr at mojavi dot org nailed it in post #7.
SimpleXMLElement->attributes()
(PHP 5 >= 5.0.1)
SimpleXMLElement->attributes() — Identifica um atributo de um elemento
Descrição
SimpleXMLElement
SimpleXMLElement attributes
([ string $ns
[, bool $is_prefix
]] )
Esta função provê os atributos e valores definidos dentro de uma tag XML.
Nota: SimpleXML tem uma regra quando do acréscimo de propriedades iterarivas na maioria dos métodos. Eles não podem ser visualizados com var_dump() nem nada que possa visualizar objetos.
Parâmetros
- ns
-
Um namespace opcional para os atributos retornados
- is_prefix
-
Padrão para FALSE
Valor Retornado
Exemplos
Exemplo #1 Interpretando uma string XML
<?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";
}
?>
O exemplo acima irá imprimir:
name="one" game="lonely"
User Contributed Notes
SimpleXMLElement->attributes()
SimpleXMLElement->attributes()
Jeff M
05-Mar-2009 01:59
05-Mar-2009 01:59
brettz9 aaat yah dot company
18-Feb-2009 03:58
18-Feb-2009 03:58
The example has a well-formedness problem: xmlns:b must equal something or be omitted
someguy at anon dot com
01-May-2008 11:07
01-May-2008 11:07
You can also use
<?php $element->attributes()->attrname; ?>
kekoav
19-Dec-2007 07:17
19-Dec-2007 07:17
For the silly looping getAttribute function below, substitute:
<?php
public function getAttribute($name){
$attrs = $this->attributes();
return $attrs[$name];
}
?>
studio at dfwstudios dot com
11-Mar-2007 01:28
11-Mar-2007 01:28
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":<br>');
print(var_dump($arrResult));
print('</pre>');
$arrResult = array();
$arrResult = $xml2->image[0]->getAttributeNames();
print('<pre>');
print('CHILD 0 ATTRIBUTE NAMES ARRAY:<br>');
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"<br>');
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.
skerr at mojavi dot org
10-Dec-2004 04:55
10-Dec-2004 04:55
You can also access the node as an array to get attributes:
<?php
$xml = simplexml_load_file('file.xml');
echo 'Attribute: ' . $xml['attribute'];
?>
christian at koch dot net
08-Nov-2004 06:35
08-Nov-2004 06:35
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 at microbecal dot com
30-Oct-2004 07:03
30-Oct-2004 07:03
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";
}
tychay at php dot net
29-Sep-2004 02:04
29-Sep-2004 02:04
BTW, It occurs to me that why do you need the function anyway? You just access it directly as (string) $object[$attribute].
tychay at php dot net
28-Sep-2004 08:31
28-Sep-2004 08:31
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
Eirik Sletteberg
12-Sep-2004 10:21
12-Sep-2004 10:21
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;
}
}
inge at elektronaut dot no
26-May-2004 02:53
26-May-2004 02:53
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;
}
}
?>

SimpleXMLElement->asXML()