0

I have a SimpleXML object that has the following node, @attributes. This is the result of simplexml_load_string() from an XML string obtained from USPS.

$xml = 

SimpleXMLElement Object
(
    [@attributes] => Array
    (
        [CLASSID] => 3
    )

    [MailService] => Priority Mail Express 1-Day
    [Rate] => 19.10
)

I realize you can do the following

$temp = $xml->attributes();    // will return object with '@attributes' note
$temp = (array)$temp;    // now in array form
echo $temp['@attributes']['CLASSID'];    // prints 3

$xml->{'Rate'};    // will return the rate (19.10) as a string

Is there a particular reason, why you want @attributes for the CLASSID? Why not jut make CLASSID the same as MailService or Rate?

laketuna
  • 3,832
  • 14
  • 59
  • 104
  • I'm sorry, I clarified my question. I'm not asking about how to access it. I'm asking about the reason behind the structure of the XML object. Please remove if necessary. – laketuna Jul 29 '13 at 16:40
  • The format of the XML is not something we can answer, you'd have to ask USPS. – Jason McCreary Jul 29 '13 at 16:43
  • ^, OK, that is true. I've noticed USPS handles data strangely. – laketuna Jul 29 '13 at 16:46
  • If you look at the answers to previous questions, you should see that this is just how SimpleXML represents XML attributes *in `var_dump` output*. There is no `@attributes` in the actual object, you never need to worry about it. – IMSoP Jul 29 '13 at 16:59
  • Your last example shows that you have not read the answers to the other questions. You do **not** need to cast to array and look up `['@attributes']`, you can just type `echo $xml['CLASSID'];`. See [the "basic usage" in the manual](http://www.php.net/manual/en/simplexml.examples-basic.php). – IMSoP Jul 29 '13 at 17:06

1 Answers1

2

Attributes of a node are treated differently from other nodes / child nodes. The @attributes is a link to the internal representation of the attributes.

To access the attributes use something like

echo $xml->attributes['CLASSID']

As IMSop points out in the comments below, a better approach to access the attributes is to use array notation. For example,

echo $xml['CLASSID']
Kami
  • 19,134
  • 4
  • 51
  • 63
  • 1
    Thanks for the answer, so `$xml->attributes()->{'CLASSID'}` gives me an XML object with the value `3`. I'm reading people using casting to get the value they want in a usable form. So, like `(int)$xml->attributes()->{'CLASSID'}` to get `3` or `(array)$xml->attributes()->{'CLASSID'}` to get `Array[0]=>3`. Is this proper? – laketuna Jul 29 '13 at 16:53
  • Yes that appears to be the way PHP handles these cases. PHP is dynamic casting so it should do it on the fly, but it may have issues with xml data or something. – Kami Jul 29 '13 at 16:54
  • Good enough for now! (but it seems like there are variants how ppl access this value - some longer and uglier than others) – laketuna Jul 29 '13 at 16:56
  • This is not really true - the `@attributes` is simply the way SimpleXML **shows** the attributes of an XML element **when outputting with `print_r`, `var_dump`, etc**. The object has "overloaded" functionality for `$node->tag` (to access child elements) and `$node['attr']` (to access attributes). The internal object is not a normal PHP object, and thinking of it as one will mislead you. – IMSoP Jul 29 '13 at 17:03
  • 1
    @Youn Regarding casting, this is often necessary to avoid confusing code that is expecting an actual string or int; `echo $xml['CLASSID'];` will work fine, but if you pass around `$xml['CLASSID']`, it remains an object linked to the original XML document, which may be undesirable (for instance, it can not be run through `serialize()`, or saved in a session). For that reason, `$class_id = (string)$xml['CLASSID']` or `$class_id = (int)$xml['CLASSID']` are often safer. – IMSoP Jul 29 '13 at 17:11