148

I am having a problem accessing the @attribute section of my SimpleXML object. When I var_dump the entire object, I get the correct output, and when I var_dump the rest of the object (the nested tags), I get the correct output, but when I follow the docs and var_dump $xml->OFFICE->{'@attributes'}, I get an empty object, despite the fact that the first var_dump clearly shows that there are attributes to output.

Anyone know what I am doing wrong here/how I can make this work?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
benjy
  • 4,664
  • 7
  • 38
  • 43
  • 5
    var_dump() is misleading, when it comes to SimpleXML. Don't take its output literally. Also, cant you access attributes using array access? e.g. $xml->OFFICE['MyAttribute']? – Frank Farmer Oct 30 '09 at 23:45
  • if you want to use ['@attributes'] you need to cast the SimpleXMLElement to array first – Enrique Feb 19 '14 at 15:59
  • 1
    Another [Access SimpleXML Attribute reference question ("How to get the value of an attribute from XML file in PHP?")](http://stackoverflow.com/q/1256796/367456) – hakre Jun 12 '14 at 18:52

10 Answers10

159

Try this

$xml->attributes()->Token
zysoft
  • 2,268
  • 1
  • 16
  • 21
  • 3
    This has been already answered [by @Artefacto](http://stackoverflow.com/a/3410579/367456). – hakre Sep 27 '12 at 12:12
  • I've tried this, and I think the page is crashing. Bora below seems to think this is a wrong format, which I'm agreeing with at this moment.. However I've seen this (your) format mentioned multiple times. Is there some nuance I'm missing? – Gerard ONeill Jan 08 '15 at 14:25
  • 2
    @GerardONeill, I don't understand why Bora says it's wrong way of accessing the attributes, it works pretty perfect. What you may be missing is that you need to call `attributes()` on the object corresponding the the right tag in your XML. Like if you have `b` then you need to do `$xml->tag->attributes()->attr` to access it. – zysoft Sep 12 '15 at 22:30
  • This returns null for me, likely not because the answer is wrong, but because the answer lacks sufficient explanation for me to use it correctly. – Goose Nov 23 '15 at 15:02
  • when I call like this - I do not get attribute value, I get SimpleXMLElement which containes 0="2001" (2001 is my value). If I use that 0 - $xml->Policy->CommlPolicy->CommlCoverage[0]->attributes()->id[0] then I againg get same 0="2001". What is that? – Darius.V Jul 03 '18 at 11:59
  • why this is not the chosen answer, the last time I lost several hours because I saw higher that not the most correct answer, I had to dig to the solution by reading full http://www.sitepoint.com/parsing-xml-with-simplexml/ article, `current($xml->attributes(current($xml->getNamespaces(true)))->noNamespaceSchemaLocation)` for retrieving concretely the schema atribute – FantomX1 Sep 07 '18 at 11:16
94

You can get the attributes of an XML element by calling the attributes() function on an XML node. You can then var_dump the return value of the function.

More info at php.net http://php.net/simplexmlelement.attributes

Example code from that page:

$xml = simplexml_load_string($string);
foreach($xml->foo[0]->attributes() as $a => $b) {
    echo $a,'="',$b,"\"\n";
}
hakre
  • 193,403
  • 52
  • 435
  • 836
Niels Bom
  • 8,728
  • 11
  • 46
  • 62
  • 9
    Interestingly, `$b` will be a `SimpleXMLElement` object so `print_r`and `var_dump` will give you weird things. You can cast it as a string (or whatever you like) to get around this. – jxmallett Apr 16 '14 at 00:39
  • Do "".$b to keep it as a string – dr_rk Mar 03 '16 at 15:35
71

I used before so many times for getting @attributes like below and it was a little bit longer.

$att = $xml->attributes();
echo $att['field'];

It should be more easy and you can get attributes following format only at once:

Standard Way - Array-Access Attributes (AAA)

$xml['field'];

Other alternatives are:

Right & Quick Format

$xml->attributes()->{'field'};

Wrong Formats

$xml->attributes()->field;
$xml->{"@attributes"}->field;
$xml->attributes('field');
$xml->attributes()['field'];
$xml->attributes->['field'];
hakre
  • 193,403
  • 52
  • 435
  • 836
Bora
  • 10,529
  • 5
  • 43
  • 73
  • 1
    I'm agreeing with your first of your wrong formats because I'm getting a page crash -- however multiple people are claiming this works. Any explanation or nuance about this? – Gerard ONeill Jan 08 '15 at 14:26
  • 1
    "Wrong formats" work. I always use first example. Why is it wrong? – Grzegorz Sep 11 '15 at 09:10
  • 3
    Technically, `$xml->attributes()->{'field'}`, `$xml->attributes()->field`, and `$f='field'; $xml->attributes()->$f;` are the same. See no reason why one is a right format and another is wrong. – zysoft Sep 12 '15 at 22:36
  • 3
    $xml->attributes()->{'field'} is correct because it's safe to use with special characters in attribute name (i.e "data-attr"). $xml->attributes()->field works only for attributes which are single alphanumeric words – vzr Jan 06 '17 at 10:39
  • 1
    Getting SimpleXMLElement when using both correct options. – Darius.V Jul 03 '18 at 12:03
  • had to explicitly cast to `string` in order to get `string` instead of `SimpleXMLElement`. `(string) $xml->attributes()['attr']` – Z. Zlatev Jan 03 '21 at 16:34
43
$xml = <<<XML
<root>
<elem attrib="value" />
</root>
XML;

$sxml = simplexml_load_string($xml);
$attrs = $sxml->elem->attributes();
echo $attrs["attrib"]; //or just $sxml->elem["attrib"]

Use SimpleXMLElement::attributes.

Truth is, the SimpleXMLElement get_properties handler lies big time. There's no property named "@attributes", so you can't do $sxml->elem->{"@attributes"}["attrib"].

Artefacto
  • 96,375
  • 17
  • 202
  • 225
15

You can just do:

echo $xml['token'];
hakre
  • 193,403
  • 52
  • 435
  • 836
Alix Axel
  • 151,645
  • 95
  • 393
  • 500
9

If you're looking for a list of these attributes though, XPath will be your friend

print_r($xml->xpath('@token'));
hakre
  • 193,403
  • 52
  • 435
  • 836
Cory Collier
  • 883
  • 1
  • 10
  • 20
4

Unfortunately I have a unique build (stuck with Gentoo for the moment) of PHP 5.5, and what I found was that

 $xml->tagName['attribute']

was the only solution that worked. I tried all of Bora's methods above, including the 'Right & Quick' format, and they all failed.

The fact that this is the easiest format is a plus, but didn't enjoy thinking I was insane trying all of the formats others were saying worked.

Njoy for what its worth (did I mention unique build?).

Gerard ONeill
  • 3,914
  • 39
  • 25
  • I would normally recommend to use array notation for attributes for the attributes in the same namespace of the element their part of. I'd say it's the easiest format (as you coin it) for a reason. array-access with a named key = attribute with simplexml element. – hakre Jul 03 '15 at 22:19
4

It helped me to convert the result of simplexml_load_file($file) into a JSON Structure and decode it back:

$xml = simplexml_load_file("$token.xml");
$json = json_encode($xml);
$xml_fixed = json_decode($json);

$try1 = $xml->structure->{"@attributes"}['value'];
print_r($try1);

>> result: SimpleXMLElement Object
(
)

$try2 = $xml_fixed->structure->{"@attributes"}['value'];
print_r($try2);

>> result: stdClass Object
(
    [key] => value
)
t2m
  • 49
  • 1
0

I want to extract string (just Song title and Artist name) from external xml file: https://nostalgicfm.ro/NowOnAir.xml This form of xml:

 <Schedule System="Jazler">
     <Event status="happening" startTime="20:31:20" eventType="song">
        <Announcement Display=""/>
      <Song title="Let It Be ">
       <Artist name="Beatles">
        <Media runTime="265.186"/>
        <Expire Time="20:35:45"/>
       </Artist>
      </Song>
     </Event>
    </Schedule>

I try this code PHP but i don't know how to extract name & title...like "Beatles - Let It Be"

  <?php
    $url = "https://nostalgicfm.ro/NowOnAir.xml";
    $xml = simplexml_load_file($url);
    print_r($xml);
    ?>

Result is an Oject:

 SimpleXMLElement Object ( [@attributes] => Array ( [System] => Jazler ) [Event] => SimpleXMLElement Object ( [@attributes] => Array ( [status] => happening [startTime] => 20:51:21 [eventType] => song ) [Announcement] => SimpleXMLElement Object ( [@attributes] => Array ( [Display] => ) ) [Song] => SimpleXMLElement Object ( [@attributes] => Array ( [title] => If You Were A Sailboat ) [Artist] => SimpleXMLElement Object ( [@attributes] => Array ( [name] => Katie Melua ) [Media] => SimpleXMLElement Object ( [@attributes] => Array ( [runTime] => 228.732 ) ) [Expire] => SimpleXMLElement Object ( [@attributes] => Array ( [Time] => 20:55:09 ) ) ) ) ) ) 
petro
  • 1
  • 2
0

Resolved it myself:

<?php 
$url = 'https://nostalgicfm.ro/NowOnAir.xml'; 
$xml = simplexml_load_file($url); 
foreach ( $xml->Event->Song->Artist->attributes() as $tag => $value ); 
foreach ( $xml->Event->Song->attributes() as $tag => $value1 ) { 
echo $value." - ".$value1.PHP_EOL; } 
?>
ouflak
  • 2,458
  • 10
  • 44
  • 49
petro
  • 1
  • 2