1

I have an XML file that I am trying to get variables off with PHP. The XML file looks like this:

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dcq="http://purl.org/dc/terms/" xmlns="http://www.skype.com/go/skypeweb">
<Status rdf:about="urn:skype:skype.com:skypeweb/1.1">

You can view the full XML file here: http://mystatus.skype.com/username.xml

I used the simplexml extension to convert the xml input into the PHP object $xml. When I attempt to navigate later in the file with:

$variable = $xml->rdf:RDF->Status->presence;

It gives me an error because of the colon in "rdf:RDF":

Parse error: syntax error, unexpected ':'

How can I either escape the colon, or navigate later in the file without changing the XML file?

hakre
  • 193,403
  • 52
  • 435
  • 836
MOOcow102
  • 91
  • 5
  • 9

2 Answers2

4

If I'm not mistaken, simplexml starts off positioned at the document (top) element, so you don't need to worry about rdf:RDF in this case. Just try:

$xml->Status->presence

In general, it seems the way to access a node with a particular namespace is to use ->children(namespaceUri), as in:

$xml->children('http://www.w3.org/2005/Atom')->entry->title

for something like this:

<a:feed xmlns:a="http://www.w3.org/2005/Atom">
   <a:entry>
      <a:title>hello</a:title>
   </a:entry>
</a:feed>
IMSoP
  • 89,526
  • 13
  • 117
  • 169
JLRishe
  • 99,490
  • 19
  • 131
  • 169
  • You can also rely on the prefix/alias in the XML not changing, and use `->children('rdf', true)` – IMSoP Jan 11 '13 at 16:09
1

Your initial code:

$variable = $xml->rdf:RDF->Status->presence;

does not work because it is creating a syntax error:

Parse error: syntax error, unexpected ':' in /test.php on line 8

The colon in the property name is not valid. PHP's common way to work with that are curly braces:

$xml->{'rdf:RDF'}->Status->presence

As you then found out you get the undefined property notice:

Notice: Trying to get property of non-object in /test.php on line 8

That is first-hand because such a property does not exists, var_dump shows that:

var_dump($xml);

class SimpleXMLElement#1 (1) {
  public $Status =>
  class SimpleXMLElement#2 (2) {
    public $statusCode =>
    string(1) "1"
    public $presence =>
    array(13) {
      [0] =>
      string(1) "1"
      ...
    }
  }
}

However, apart from that, even if there would be a children with a namespace prefixed element name, it would not work that way. This would just never work, so always such a property is not defined.

However what the previous dump outlines is that there is the property you're looking for: $Status:

$variable = $xml->Status->presence;

So you were just looking in the wrong place. The var_dump($variable) is:

class SimpleXMLElement#4 (13) {
    string(1) "1"
    string(7) "Offline"
    string(12) "Déconnecté"
    string(7) "Offline"
    string(15) "オフライン"
    string(6) "離線"
    string(6) "脱机"
    string(7) "Offline"
    string(7) "Offline"
    string(12) "Non in linea"
    string(12) "Desconectado"
    string(15) "Niepodłączony"
    string(7) "Offline"
}
hakre
  • 193,403
  • 52
  • 435
  • 836
  • Voted down for trying to explain SimpleXML nodes in terms of `var_dump()` and PHP object properties. This is not a valid approach, because SimpleXML does magic to overload the meaning of `->`, and because the colon in the XML tag represents a namespace association, not just a tag name with a colon in. – IMSoP Jan 11 '13 at 16:13
  • @IMSoP the argument in this case is moot. When you get the error and the property is not in there any-way (which *is* the case here), it's perfectly fine to outline the next step (as done) to access existing properties. As you can see, the existing properties are shown by `var_dump` *even* this is `SimpleXMLElement`. So basically with this point your comment is wrong. Take note of the difference between Elements (Properties) and Attributes (`var_dump` does not show them as array indices of the object but indirect via `@attributes`). – hakre Jan 12 '13 at 13:36
  • @hakre It may show something seemingly relevant in this case, but in general trying to judge what a SimpleXML object contains using `var_dump` is likely to lead to some confusingly wrong conclusions, and is a bad habit to encourage. For instance, child elements or attributes in a different namespace are simply invisible, as is any text in or near a CDATA node. The steps you outline here make sense only because you already knew the answers; a good answer would give someone an approach to future problems, and `var_dump` is not a good approach in many cases. – IMSoP Jan 12 '13 at 14:35
  • @IMSoP: As far as the for a concrete XML element and it's children's names is concerned, `var_dump` works pretty well for that. That's just the point here and what I wanted to highlight to you. Sure, you can always warn (which I precisely did for the namespace-prefixed-elements), but don't warn for the parts where no warn is necessary. For future reference I suggest: [“At sign” @ in SimpleXML object?](http://stackoverflow.com/q/4327873/367456) - Also I'd like to see your comment and downvote as well here: http://stackoverflow.com/a/14292760/367456 :) – hakre Jan 12 '13 at 15:38
  • @hakre I stand by my point that your answer seems to encourage reliance on `var_dump`, and that this may cause confusion in other situations. Perhaps a general warning of "`var_dump` doesn't always show what you need for SimpleXML objects, but in this case it gives us a good clue"? Also remember that a lot of people won't know enough to connect their "tag with a colon in" to your "children with a namespace prefixed element name". – IMSoP Jan 13 '13 at 17:32
  • @IMSoP: I find it somewhat funny that your point is to prefer a warning while a clear warning is there. You also do not differ and over-generalize. But stand, otherwise I have the feeling it would mean to you that you would fall. So I don't want to experience how that would feel, so better stand. - Oh and the downvote that is so important to you, you don't even do on questions that actually deserve it more, right? – hakre Jan 13 '13 at 21:24
  • @hakre I disagree that a clear warning is there. If you mean the sentence beginning "However, apart from that, ..." it wouldn't be at all clear to a non-expert what you were talking about. Like I say "namespace prefixed element name" will mean absolutely nothing to many of the people who use this site, and "it would not work that way" is about as vague as you can get. – IMSoP Jan 13 '13 at 21:30
  • Well, actually child elements are visible per their name in the `var_dump`, only non-existent (as written) and namespace'd ones (as written) are not. I wonder how that is vague, looks pretty precise to me. But probably you might finally tell where that is wrong. – hakre Jan 13 '13 at 21:32
  • @hakre Yes, I accept that in this case, `var_dump` leads to the right conclusion, but only because the `Status` node **is** there, because it happens not to be in a prefixed namespace. Nowhere do you explain what's special about the `rdf:RDF` node, and where to look for it if the actual answer hadn't been a much simpler mistake about already being inside it. – IMSoP Jan 13 '13 at 23:49