-1
SimpleXMLElement Object
(
    [SMSMessage] => SimpleXMLElement Object
        (
            [Sid] => xyz
            [DateUpdated] => 2013-05-02 18:43:19
            [DateCreated] => 2013-05-02 18:43:19
            [DateSent] => 1970-01-01 05:30:00
            [AccountSid] => xx
            [To] => 09011148771
            [From] => xx
            [Body] => Hello
            [BodyIndex] => SimpleXMLElement Object
                (
                )

            [Status] => sending
            [Direction] => outbound-api
            [Price] => SimpleXMLElement Object
                (
                )

            [ApiVersion] => SimpleXMLElement Object
                (
                )

            [Uri] => /v1/Accounts/xx/Sms/Messages/xyz
        )

)

I tried:

$xml->Sid;

But it returns SimpleXMLElement Object ( )

I also tried $xml->title, which also returned the same SimpleXMLElement Object ( )

How to get the Sid from the above XMl

hakre
  • 193,403
  • 52
  • 435
  • 836
Archie.bpgc
  • 23,812
  • 38
  • 150
  • 226
  • 2
    try $xml->SMSMessage->Attributes('Sid'); – aleation May 02 '13 at 13:17
  • I got the same `SimpleXMLElement Object ( )` – Archie.bpgc May 02 '13 at 13:20
  • can you var_export() the simpleXMLElement or the actual XML code so I can give it a try ? – aleation May 02 '13 at 13:21
  • I could get it using `$te = (array)$xml->SMSMessage->Sid; $sid = $te[0];` Is it the right way? – Archie.bpgc May 02 '13 at 13:31
  • Have you tried $xml->SMSMessage->Sid ? For me it works, try it out, see my answer below – aleation May 02 '13 at 13:42
  • 1
    @Archie.bpgc: No. Please see [simplexml basic usage in the PHP Manual](http://php.net/simplexml.examples-basic). It explains this pretty well, see Example #1 and #2. – hakre May 02 '13 at 13:42
  • @hakre That's one of thee replies I would have written, but I have to recognize that it could be a bit confusing, as I started to work with XML's and simpleXML few weeks ago, and found it more challenging than I Expected. – aleation May 02 '13 at 13:45
  • 2
    @aleation: Yes, there is a lot of magic. Which means, better read through the basic usage examples *once*. Then search for questions here on SO. We have some better answers in earlier answers, and very little in newer ones (not that they are generally bad but often quickly typed). I even edit older answers and add new methods to them if I see fit, so to make this a better place. – hakre May 02 '13 at 13:46
  • 1
    This read might also be interesting: [SimpleXML - echo / print_r return different values](http://stackoverflow.com/q/3236801/367456) - just for the info that `print_r` and *SimpleXML* does not always work straight-forward with each other because of the magic. – hakre May 02 '13 at 13:54
  • 1
    I agree with everything @hakre has said about reading the manual and previous questions, and would add my usual plug for my debug functions which attempt to do a better job than `print_r` at representing the magic of SimpleXML: https://github.com/IMSoP/simplexml_debug – IMSoP May 02 '13 at 16:33

4 Answers4

1

I've been Fiddling a bit and recreated a structure similar to yours:

$string='<?xml version="1.0"?>
<xml>
    <SMSMessage>
        <Sid>xyz</Sid>
        <DateUpdated>2013-05-02 18:43:19</DateUpdated>
    </SMSMessage>
</xml>';

$xml = new SimpleXMLElement($string);

print_r($xml);

this outputs:

SimpleXMLElement Object
(
    [SMSMessage] => SimpleXMLElement Object
    ( 
        [Sid] => xyz
        [DateUpdated] => 2013-05-02 18:43:19
    )
)

Which is equal to yours. And I could print xyz doing:

echo $xml->SMSMessage->Sid;

Try it out, you might be missing some parent node or something.

aleation
  • 4,796
  • 1
  • 21
  • 35
0

Your Method: To do it the way you want, I think you'd have to go one step further with your call since the SimpleXMLObject is parent to another SimpleXMLObject. E.g. $xml->SMSMessage->Sid;. I generally recommend using xpath with XML because in most cases, you want to jump directly to a specific node and not traverse the whole XML tree. For example, this: $xml->xpath('//[node]') is quicker than $xml->tier1->tier2->tier3->etc.

Preferred Method: Assuming $xml represents the SimpleXMLObject you've posted, you can access Sid like this: $xml->xpath('//Sid');. This should skip directly to the "Sid" node in the tree.

Chad
  • 714
  • 2
  • 9
  • 26
  • It's a matter of opinion, obviously, but I completely disagree about XPath. Most of the time you absolutely want to know the structure of the document, because there might be another node with the same name somewhere else which you can safely ignore. – IMSoP May 02 '13 at 16:27
  • Its not a matter of opinion. This: `$xml->xpath('//[node]')` is easier and cleaner node access than this: `$xml->tier1->tier2->tier3`. There's always an API that may have a simpler structure but in most cases, especially with paid API services, there's a lot of unnecessary XML boilerplate. You're welcome to attempt provide a better alternative and state why xpath is not preferred over a manual access method. – Chad May 02 '13 at 17:11
  • @cwscribner: Yes, xpath is comfortable but I don't think that was what the issue @IMSoP meant. IMHO I think you should know about both methods. Also the "correct" example would be -`$xml->xpath('tier1/tier2/tier3/etc')` if you need it distinct which you not show in the example. So it's not really fair to compare tow different things here. Just saying, xpath *is* fine. I use it very often. – hakre May 02 '13 at 17:29
  • XPath is not less "manual" than traversal using an API like SimpleXML; the difference in your example is that it is a *search*, rather than a *traversal*. Both have their place, but they are *not equivalent*, and it is certainly not always "cleaner" to use a search. Consider `$doc->xpath('//Title');` - this is fine if the document has one `Title` node, but if later a `Title` is added on each section, it becomes ambiguous. `$doc->CoverPage->Title`, OTOH, shows exactly what is being accessed, and is more resistant to incidental changes elsewhere in the document. – IMSoP May 02 '13 at 17:54
  • @IMSoP It's empirically less manual in terms of typing and cleaner in terms of code formatting than typing each individual node. That's not something you can argue. In terms of ambiguity, that's more the fault of the SimpleXMLElement Object default behavior. If multiple title nodes are nested at the same level, they're combined into an array of titles. This is true for any node name at the same level. So, the ambiguity is not exacerbated by using xpath. xpath actually breaks down the target nodes into individual objects that can then be operated on. That's why xpath is preferable. – Chad May 02 '13 at 19:00
  • @cwscribner I suspect we're going to have to agree to disagree. I have no idea what you're on about with multiple nodes in SimpleXML, which are no harder or easier to loop through with or without XPath. My point about ambiguity is that `$foo->xPath('//bar')` could match both `$foo->heading->bar` and the completely unrelated `$foo->item[0]->info->bar`. It's like storing all your URLs as Google search terms (OK, that's an exaggeration, but it's the same principle). – IMSoP May 02 '13 at 20:54
0

In simplexml you always have to cast your values - so you have to do this:

echo $xml->Sid;

(echo automatically casts). Or explicitly:

$string = (string) $xml->id;
hakre
  • 193,403
  • 52
  • 435
  • 836
Adidi
  • 5,097
  • 4
  • 23
  • 30
  • Note that `echo` isn't a function, so you don't need those brackets. (Adding them unnecessarily can lead people to misinterpret code, as PHP will not be treating them the way you think.) – IMSoP May 02 '13 at 16:36
  • 1
    Oh, and `echo` is also the worst example of needing to cast the value to a string, since it explicitly has string context, so will auto-cast any value for you. – IMSoP May 02 '13 at 16:55
-1

if you have:

$string='<?xml version="1.0"?>
<xml>
    <SMSMessage>
        <Sid>xyz</Sid>
        <DateUpdated>2013-05-02 18:43:19</DateUpdated>
    </SMSMessage>
</xml>';

$xml = new SimpleXMLElement($string);

print_r('<pre>');
$Sid = (array)($xml->SMSMessage->Sid);
print_r($Sid[0]);
print_r($xml);

You can access Sid like so $Sid = (array)(xml->SMSMessage->Sid); echo $Sid[0]; But if you rather use array you can do this:

$string='<?xml version="1.0"?>
<xml>
    <SMSMessage>
        <Sid>xyz</Sid>
        <DateUpdated>2013-05-02 18:43:19</DateUpdated>
    </SMSMessage>
</xml>';

$array= json_decode(json_encode(new SimpleXMLElement($string)), true);

print_r('<pre>');
print_r($array['SMSMessage']['Sid']);
print_r($array);
  • 1
    Not sure why you're getting tangled up converting everything to array. SimpleXML is designed to be a very efficient and natural-feeling way of traversing an XML document; converting the whole thing to some other structure somewhat defeats the point. – IMSoP May 02 '13 at 16:35