trouble destructing xml
When all else fails, and #xml, ##php and #drupal-support come up empty...ask the folks who actually code :) I have an xml structure that has <this> <that parm1="a" parm2="b" parm3="c">red</that> <that parm1="e" parm2="f" parm3="d">blue</that> </this> I've tried simplexml and a few third-party scripts, one that loads the xml into an associative array rather than an object, and nothing lets me get at 'red' or 'blue'. When I use dsm() on the results, for example, in the case of the object with simplexml I get only one 'that' and do not get its contents. When I use the script that creates the array, I get both that's, and all their parms as elements, but not the colors. I'm curious what else people are using. Jeff -- /I am a non sequitur. Beware, the contents were packaged where peanuts are processed./ Ayen Designs 388 Bullsboro Drive #105 · Newnan, Georgia 30263 404-271-9734 Web:ayendesigns.com <http://ayendesigns.com/> Blog: theAccidentalCoder.com <http://theaccidentalcoder.com/> Drupal: j. ayen green <http://drupal.org/user/367108> (367108) IRQ: j_ayen_green IM (Yahoo) baalwww (MSN) baalwww@yahoo.com Skype: ayendesigns | Facebook: ayendesigns | Twitter: @ayendesigns Ayen Designs is the computer services division of
I use SimpleXML pretty much exclusively for this stuff: $data='<this> <that parm1="a" parm2="b" parm3="c">red</that> <that parm1="e" parm2="f" parm3="d">blue</that> </this>'; $xml=simplexml_load_string($data); foreach ($xml->that as $item){ print_r($item); echo "<hr>"; } Returns: SimpleXMLElement Object ( [@attributes] => Array ( [parm1] => a [parm2] => b [parm3] => c ) [0] => red ) ------------------------------------------------------------------------ SimpleXMLElement Object ( [@attributes] => Array ( [parm1] => e [parm2] => f [parm3] => d ) [0] => blue ) Which is what it should. You can also use XPath to get at what you want: $xpath = $xml->xpath('/this/that'); Which would return an array of each <that> item along with the attributes. Jamie Holly http://www.intoxination.net http://www.hollyit.net On 3/24/2011 9:09 PM, jeff@ayendesigns.com wrote:
When all else fails, and #xml, ##php and #drupal-support come up empty...ask the folks who actually code :)
I have an xml structure that has
<this> <that parm1="a" parm2="b" parm3="c">red</that> <that parm1="e" parm2="f" parm3="d">blue</that> </this>
I've tried simplexml and a few third-party scripts, one that loads the xml into an associative array rather than an object, and nothing lets me get at 'red' or 'blue'. When I use dsm() on the results, for example, in the case of the object with simplexml I get only one 'that' and do not get its contents. When I use the script that creates the array, I get both that's, and all their parms as elements, but not the colors.
I'm curious what else people are using.
Jeff -- /I am a non sequitur. Beware, the contents were packaged where peanuts are processed./
Ayen Designs 388 Bullsboro Drive #105 · Newnan, Georgia 30263 404-271-9734 Web:ayendesigns.com <http://ayendesigns.com/> Blog: theAccidentalCoder.com <http://theaccidentalcoder.com/> Drupal: j. ayen green <http://drupal.org/user/367108> (367108) IRQ: j_ayen_green IM (Yahoo) baalwww (MSN) baalwww@yahoo.com Skype: ayendesigns | Facebook: ayendesigns | Twitter: @ayendesigns
Ayen Designs is the computer services division of
I use simplexml to do this.... IF no one else has responded by the time i get back home I will happily post some code, or i can rendezvous with you on irc. I breath this stuff at work ;) Sent from my iPad On Mar 24, 2011, at 6:09 PM, jeff@ayendesigns.com wrote:
When all else fails, and #xml, ##php and #drupal-support come up empty...ask the folks who actually code :)
I have an xml structure that has
<this> <that parm1="a" parm2="b" parm3="c">red</that> <that parm1="e" parm2="f" parm3="d">blue</that> </this>
I've tried simplexml and a few third-party scripts, one that loads the xml into an associative array rather than an object, and nothing lets me get at 'red' or 'blue'. When I use dsm() on the results, for example, in the case of the object with simplexml I get only one 'that' and do not get its contents. When I use the script that creates the array, I get both that's, and all their parms as elements, but not the colors.
I'm curious what else people are using.
Jeff -- I am a non sequitur. Beware, the contents were packaged where peanuts are processed. <ayenlogo>Ayen Designs 388 Bullsboro Drive #105 · Newnan, Georgia 30263 404-271-9734 Web:ayendesigns.com Blog: theAccidentalCoder.com Drupal: j. ayen green (367108) IRQ: j_ayen_green IM (Yahoo) baalwww (MSN) baalwww@yahoo.com Skype: ayendesigns | Facebook: ayendesigns | Twitter: @ayendesigns
Ayen Designs is the computer services division of <acmelogo>
Thanks for the replies...but no joy yet. The XML data looks like this (I'm minimizing it) <?xml version="1.0" encoding="UTF-8" standalone="no"?> <document> <channels> <channel> <episode> <episode-content> <doc> <cncpts> <cn doc="true" er="164" kw="false" ne="true" sc="9.647706" sr="164" t="unk">here I am</cn> and I have $t = simplexml_load_file('text.xml','SimpleXMLElement', LIBXML_NOCDATA); dsm($t); foreach ($t->channels->channel->nlp->episode->{episode-content}->doc->cncpts->cn as $k) { $dsm($k); } The first dsm immediately after loading the file does not show the seven 'cn' elements that I have, and the second is empty because the foreach complains.
I'm serious, this is exactly what QueryPath was written for. The QueryPath code for what you are asking would be: foreach (qp('text.xml', 'cn') as $cn) { // print an attr dpm('doc attr: ' . $cn->attr('doc')); // print the PCDATA text dpm('text: ' . $cn->text()); } Since QueryPath takes any old CSS3 selectors, you could do more complicated queries if you wanted. For example, if you only wanted CN elements where the doc attr was true, you'd just do this: foreach (qp('text.xml', 'cn[doc=true]') as $cn) { dpm('text: ' . $cn->text()); } Not to mention that QueryPath is actually faster than most SimpleXML operations because it traverse the DOM tree more efficiently. And you can download QueryPath just like any other Drupal module. Honestly, if you're not keen on the QueryPath idea, you should just use PHP's DOM interface. It's more efficient than SimpleXML, which is a HORRIBLE data structure for working with XML anyway. It's inefficient and it's full of the sorts of oddities that you are describing right now. On Thu, Mar 24, 2011 at 8:58 PM, <jeff@ayendesigns.com> wrote:
Thanks for the replies...but no joy yet. The XML data looks like this (I'm minimizing it)
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <document> <channels> <channel> <episode> <episode-content> <doc> <cncpts> <cn doc="true" er="164" kw="false" ne="true" sc="9.647706" sr="164" t="unk">here I am</cn>
and I have
$t = simplexml_load_file('text.xml','SimpleXMLElement', LIBXML_NOCDATA); dsm($t); foreach ($t->channels->channel->nlp->episode->{episode-content}->doc->cncpts->cn as $k) { $dsm($k); }
The first dsm immediately after loading the file does not show the seven 'cn' elements that I have, and the second is empty because the foreach complains.
Matt, perfecto! Worked like a charm the first time. I had a chuckle...your second message came while I was changing the code to qp. It wasn't any discomfort or raised eyebrow on my part, I tried the simplexml stuff again first since it was already coded that way. Thanks!! On 03/24/2011 10:20 PM, Matt wrote:
I'm serious, this is exactly what QueryPath was written for. The QueryPath code for what you are asking would be:
Oh, good. I hate to see anyone agonize over SimpleXML. Matt On Thu, Mar 24, 2011 at 9:39 PM, <jeff@ayendesigns.com> wrote:
Matt, perfecto! Worked like a charm the first time. I had a chuckle...your second message came while I was changing the code to qp. It wasn't any discomfort or raised eyebrow on my part, I tried the simplexml stuff again first since it was already coded that way.
Thanks!!
On 03/24/2011 10:20 PM, Matt wrote:
I'm serious, this is exactly what QueryPath was written for. The QueryPath code for what you are asking would be:
In QueryPath it would be: <?php $xml = '<this> <that parm1="a" parm2="b" parm3="c">red</that> <that parm1="e" parm2="f" parm3="d">blue</that> </this>'; // Loop through all <that> elements... foreach (qp($xml, 'that') as $that) { // Get the text for each <that> element. print $that->text(); } ?> On Thu, Mar 24, 2011 at 8:09 PM, <jeff@ayendesigns.com> wrote:
When all else fails, and #xml, ##php and #drupal-support come up empty...ask the folks who actually code :)
I have an xml structure that has
<this> <that parm1="a" parm2="b" parm3="c">red</that> <that parm1="e" parm2="f" parm3="d">blue</that> </this>
I've tried simplexml and a few third-party scripts, one that loads the xml into an associative array rather than an object, and nothing lets me get at 'red' or 'blue'. When I use dsm() on the results, for example, in the case of the object with simplexml I get only one 'that' and do not get its contents. When I use the script that creates the array, I get both that's, and all their parms as elements, but not the colors.
I'm curious what else people are using.
Jeff -- *I am a non sequitur. Beware, the contents were packaged where peanuts are processed.*
Ayen Designs 388 Bullsboro Drive #105 · Newnan, Georgia 30263 404-271-9734 Web:ayendesigns.com Blog: theAccidentalCoder.com <http://theaccidentalcoder.com/> Drupal: j. ayen green <http://drupal.org/user/367108> (367108) IRQ: j_ayen_green IM (Yahoo) baalwww (MSN) baalwww@yahoo.com Skype: ayendesigns | Facebook: ayendesigns | Twitter: @ayendesigns
Ayen Designs is the computer services division of
On 3/24/11 7:09 PM, jeff@ayendesigns.com wrote:
When I use dsm() on the results, for example, in the case of the object with simplexml I get only one 'that' and do not get its contents.
It looka like you've already found the XML data you're looking for, but it might be useful for future reference to know that SimpleXML doesn't play well with object inspection such as dsm(): http://www.php.net/manual/en/simplexmlelement.children.php "Note: SimpleXML has made a rule of adding iterative properties to most methods. They cannot be viewed using var_dump() or anything else which can examine objects." So the data was in your SimpleXML; you just couldn't see it with dsm(). -- Scott Reynen MakeDataMakeSense.com
Regarding introspection..... Not quite true. I use print_r on simplexml objects all the time with dsm. drupal_set_message('<pre>' . print_r($xml,1) . '</pre>'); although it sounds like the drupal community is pretty "down" on its use. I found it useful because it gave a lot of these xml as an object functions long before the other libraries mentioned were around. Using DOM to iterate hierarchical xml is just silly, as it will take youi twice as many lines of code to do pretty much anything. The other thing most people don't know is you can get the interior text of a simplexml element with a simple string cast. (string)$node. The iterators are exactly what makes it useful. FYI: The xpath mehod of simplexml would've solved the users problem with the straight property access. I'll start giving qp a look , but this community has frowned on bundling third party libraries with drupal contrib modules in the past. Have we changed our mind regarding this one? I no Dave On Mar 24, 2011, at 8:13 PM, Scott Reynen wrote:
On 3/24/11 7:09 PM, jeff@ayendesigns.com wrote:
When I use dsm() on the results, for example, in the case of the object with simplexml I get only one 'that' and do not get its contents.
It looka like you've already found the XML data you're looking for, but it might be useful for future reference to know that SimpleXML doesn't play well with object inspection such as dsm():
http://www.php.net/manual/en/simplexmlelement.children.php
"Note: SimpleXML has made a rule of adding iterative properties to most methods. They cannot be viewed using var_dump() or anything else which can examine objects."
So the data was in your SimpleXML; you just couldn't see it with dsm().
-- Scott Reynen MakeDataMakeSense.com
On 3/24/11 10:58 PM, David Metzler wrote:
Regarding introspection..... Not quite true. I use print_r on simplexml objects all the time with dsm.
drupal_set_message('<pre>' . print_r($xml,1) .'</pre>');
Hmm. That's never worked for me, and the note on php.net suggests it doesn't work for others. But if it works for you, great. I do want to note, though, that dsm() is not a shorthand for drupal_set_message(); it's a completely different function in the devel module.
although it sounds like the drupal community is pretty "down" on its use.
For my part, I didn't mean to suggest I'm "down" on SimpleXML, rather that it may be working fine (though it sounds like it wasn't for Jeff) even if inspection suggests otherwise.
I'll start giving qp a look , but this community has frowned on bundling third party libraries with drupal contrib modules in the past.
Kevin O has already pointed out QueryPath is okay on licensing, but that's not enough to make it okay for Drupal.org. The policy against hosting third party work on Drupal.org goes beyond licensing concerns. See: http://drupal.org/node/422996 That said, QueryPath is _not_ third party. The maintainer of the module on Drupal.org is the lead developer of the QueryPath project at querypath.org. It's first party. -- Scott Reynen MakeDataMakeSense.com
Yeah, it would be a rather odd argument for someone to make that even though I wrote QueryPath and the QueryPath module, I have to remove QueryPath from the QueryPath module simply because it is separable from Drupal (and because I have released the non-Drupal part separately from the Drupal module). Matt On Fri, Mar 25, 2011 at 8:45 AM, Scott Reynen <scott@makedatamakesense.com> wrote:
On 3/24/11 10:58 PM, David Metzler wrote:
Regarding introspection..... Not quite true. I use print_r on simplexml objects all the time with dsm.
drupal_set_message('<pre>' . print_r($xml,1) .'</pre>');
Hmm. That's never worked for me, and the note on php.net suggests it doesn't work for others. But if it works for you, great. I do want to note, though, that dsm() is not a shorthand for drupal_set_message(); it's a completely different function in the devel module.
although it sounds like the drupal community is pretty "down" on its use.
For my part, I didn't mean to suggest I'm "down" on SimpleXML, rather that it may be working fine (though it sounds like it wasn't for Jeff) even if inspection suggests otherwise.
I'll start giving qp a look , but this community has frowned on bundling third party libraries with drupal contrib modules in the past.
Kevin O has already pointed out QueryPath is okay on licensing, but that's not enough to make it okay for Drupal.org. The policy against hosting third party work on Drupal.org goes beyond licensing concerns. See:
That said, QueryPath is _not_ third party. The maintainer of the module on Drupal.org is the lead developer of the QueryPath project at querypath.org. It's first party.
-- Scott Reynen MakeDataMakeSense.com
For this (and that!) xpath is your friend. See this example at http://php.net/manual/en/simplexmlelement.xpath.php $string = <<<XML <a> <b> <c>text</c> <c>stuff</c> </b> <d> <c>code</c> </d> </a> XML; $xml = new SimpleXMLElement($string); /* Search for <a><b><c> */ $result = $xml->xpath('/a/b/c'); while(list( , $node) = each($result)) { echo '/a/b/c: ',$node,"\n"; } /* Relative paths also work... */ $result = $xml->xpath('b/c'); while(list( , $node) = each($result)) { echo 'b/c: ',$node,"\n"; } Victor Kane http://awebfactory.com.ar http://projectflowandtracker.com On Thu, Mar 24, 2011 at 10:09 PM, <jeff@ayendesigns.com> wrote: When all else fails, and #xml, ##php and #drupal-support come up empty...ask the folks who actually code :) I have an xml structure that has <this> <that parm1="a" parm2="b" parm3="c">red</that> <that parm1="e" parm2="f" parm3="d">blue</that> </this> I've tried simplexml and a few third-party scripts, one that loads the xml into an associative array rather than an object, and nothing lets me get at 'red' or 'blue'. When I use dsm() on the results, for example, in the case of the object with simplexml I get only one 'that' and do not get its contents. When I use the script that creates the array, I get both that's, and all their parms as elements, but not the colors. I'm curious what else people are using. Jeff -- I am a non sequitur. Beware, the contents were packaged where peanuts are processed. Ayen Designs 388 Bullsboro Drive #105 · Newnan, Georgia 30263 404-271-9734 Web:ayendesigns.com Blog: theAccidentalCoder.com Drupal: j. ayen green (367108) IRQ: j_ayen_green IM (Yahoo) baalwww (MSN) baalwww@yahoo.com Skype: ayendesigns | Facebook: ayendesigns | Twitter: @ayendesigns Ayen Designs is the computer services division of On Thu, Mar 24, 2011 at 10:09 PM, <jeff@ayendesigns.com> wrote:
When all else fails, and #xml, ##php and #drupal-support come up empty...ask the folks who actually code :)
I have an xml structure that has
<this> <that parm1="a" parm2="b" parm3="c">red</that> <that parm1="e" parm2="f" parm3="d">blue</that> </this>
I've tried simplexml and a few third-party scripts, one that loads the xml into an associative array rather than an object, and nothing lets me get at 'red' or 'blue'. When I use dsm() on the results, for example, in the case of the object with simplexml I get only one 'that' and do not get its contents. When I use the script that creates the array, I get both that's, and all their parms as elements, but not the colors.
I'm curious what else people are using.
Jeff -- *I am a non sequitur. Beware, the contents were packaged where peanuts are processed.*
Ayen Designs 388 Bullsboro Drive #105 · Newnan, Georgia 30263 404-271-9734 Web:ayendesigns.com Blog: theAccidentalCoder.com <http://theaccidentalcoder.com/> Drupal: j. ayen green <http://drupal.org/user/367108> (367108) IRQ: j_ayen_green IM (Yahoo) baalwww (MSN) baalwww@yahoo.com Skype: ayendesigns | Facebook: ayendesigns | Twitter: @ayendesigns
Ayen Designs is the computer services division of
I hadn't been concluding I had trouble with simplexml only because dsm() didn't show anything, more that dsm reinforced the situation. I was referring to what should have been the element in code and coming up empty, or with in error, in the case of foreach. Xpath doesn't work for some reason. I presume there could be something unusual with the file layout, since it's full of cpath stuff and I'm excerpting it here. It might, in part, have something to do with some of the path names being hyphenated. I know php has a problem with that when creating an object reference unless it is encased in {}. Not only does querypath work with the tag name, but it worked too well at first. There are, apparently, other such tags elsewhere in the data, and I was receiving output for all of them. It turns out you can do some wonderful things with querypath. First, I provided further context by using: foreach (qp('text.xml', parent-tag-name)->children as $item) but the problem with that was I received all the children, which included the tags I needed, but also others. So, you can also do this: foreach (qp('text.xml', parent-tag-name)->children(child-tag-name) as $item) and then only receive the correct tags in the correct concept, such as xpath would have done with parent-tag/child-tag had it worked in this case. Jeff
If you wanted, you can avoid the children() calls by writing a slightly more complex selector in qp(). You can use CSS3-style selectors to get the right relationships. Example: $xml = '<doc> <a> <b> <c>foo</c> </b> <c>another c</c> </a> <c>a third c</c> </doc>' // This will be 3, since there are 3 <c> elements qp($xml, 'c')->size() // This will match both of the <c> tags underneath the <a>, so it will be 2. qp($xml 'a c')->size() // This will match just the <c>'s that are direct descendants of <b>'s that are direct descendants of <a>'s. qp($xml, 'a>b>c')->size(); The selector syntax is exactly the same as what you would use if you were writing a stylesheet: a>b>c { color: red; } Matt On Fri, Mar 25, 2011 at 8:29 AM, <jeff@ayendesigns.com> wrote:
I hadn't been concluding I had trouble with simplexml only because dsm() didn't show anything, more that dsm reinforced the situation. I was referring to what should have been the element in code and coming up empty, or with in error, in the case of foreach.
Xpath doesn't work for some reason. I presume there could be something unusual with the file layout, since it's full of cpath stuff and I'm excerpting it here. It might, in part, have something to do with some of the path names being hyphenated. I know php has a problem with that when creating an object reference unless it is encased in {}.
Not only does querypath work with the tag name, but it worked too well at first. There are, apparently, other such tags elsewhere in the data, and I was receiving output for all of them. It turns out you can do some wonderful things with querypath. First, I provided further context by using:
foreach (qp('text.xml', parent-tag-name)->children as $item)
but the problem with that was I received all the children, which included the tags I needed, but also others. So, you can also do this:
foreach (qp('text.xml', parent-tag-name)->children(child-tag-name) as $item)
and then only receive the correct tags in the correct concept, such as xpath would have done with parent-tag/child-tag had it worked in this case.
Jeff
participants (7)
-
Dave Metzler -
David Metzler -
Jamie Holly -
jeff@ayendesigns.com -
Matt -
Scott Reynen -
Victor Kane