SimpleXML and Default Cast To String

php.internals

Blake Schwendiman

22 years ago
Hello, If I have an XML document such: . <para> This is some <i>test</i> text. </para> . When I use simplexml_load_string and then do: print( $obj->para ); The result is: "This is some text." Note that the embedded <i></i> text is missing. Internally, the cast is made using the xmlNodeListGetString function. Is there any reason that it makes more sense to do that rather than use the xmlNodeGetContent function. The latter function returns the complete text. I am a newbie to most of this, so there may be many reasons for the choice. If the former method is preferred, would it be possible to add another method for retrieving the text of a node using the xmlNodeGetContent function. I have added such a method to my beta 3 installation called toString() and it works fine. I would probably rename it for general redistribution. Thanks in advance! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Blake Schwendiman Software Development :: http://www.lulu.com/intechrabooks :: In-depth software development books priced right

Adam Maccabee Trachtenberg

22 years ago
On Wed, 7 Jan 2004, Blake Schwendiman wrote:
> Note that the embedded <i></i> text is missing. Internally, the cast is > made using the xmlNodeListGetString function. Is there any reason that > it makes more sense to do that rather than use the xmlNodeGetContent > function. The latter function returns the complete text. I am a newbie > to most of this, so there may be many reasons for the choice.
I would say this is a bug and we should switch to xmlNodeGetContent instead. -adam
-- adam@trachtenberg.com

Marcus Börger

22 years ago
Hello Adam, Wednesday, January 7, 2004, 10:54:24 PM, you wrote:
> On Wed, 7 Jan 2004, Blake Schwendiman wrote:
>> Note that the embedded <i></i> text is missing. Internally, the cast is >> made using the xmlNodeListGetString function. Is there any reason that >> it makes more sense to do that rather than use the xmlNodeGetContent >> function. The latter function returns the complete text. I am a newbie >> to most of this, so there may be many reasons for the choice.
> I would say this is a bug and we should switch to xmlNodeGetContent > instead.
From my opinion the current behavior is perfect because i see simplexml from an xml developers side and not from an html developers side. The former must typically know exactly where his strings comme from while the latter has only text to deal with and often has situations where he needs to filter out formatting tags like the <i> in the example. So i'd say let us add a method for returning the complete content. Adam could you do that? Best regards, Marcus mailto:helly@php.net

Adam Maccabee Trachtenberg

22 years ago
On Thu, 8 Jan 2004, Marcus Boerger wrote:
> From my opinion the current behavior is perfect because i see simplexml from > an xml developers side and not from an html developers side. The former must > typically know exactly where his strings comme from while the latter has > only text to deal with and often has situations where he needs to filter out > formatting tags like the <i> in the example.
All of my SimpleXML work is strictly XML, too. However, my thought was that I could always call strip_tags() to eliminate the information I didn't want, but there was no apply_tags() function to do the reverse. :) Therefore, it was better to use the other method.
> So i'd say let us add a method for returning the complete content. Adam > could you do that?
That wouldn't be too difficult (although I am busy for the next day or two). However, as much as I loathe toggles, I'm wondering if it wouldn't be better to make this an object-wide setting. My thought are that on an object-by-object basis, you either always want tags or never want them. Something like: $sxe = simplexml_load_file('doc.xml'); $sxe->displayTags = true; This would keep the interface clean. Or would that just confuse things with more magic? Also, what would the default behavior should be? I can argue both sides of the issue right now. :) -adam
-- adam@trachtenberg.com

Marcus Börger

22 years ago
Hello Adam, Thursday, January 8, 2004, 12:59:19 AM, you wrote:
> On Thu, 8 Jan 2004, Marcus Boerger wrote:
>> From my opinion the current behavior is perfect because i see simplexml from >> an xml developers side and not from an html developers side. The former must >> typically know exactly where his strings comme from while the latter has >> only text to deal with and often has situations where he needs to filter out >> formatting tags like the <i> in the example.
> All of my SimpleXML work is strictly XML, too. However, my thought was > that I could always call strip_tags() to eliminate the information I > didn't want, but there was no apply_tags() function to do the > reverse. :) Therefore, it was better to use the other method.
Well there's ext/SPL in PECL. A SimpleXML Object is also a Iterator and it is a RecursiveIterator if ext/SPL is build in. Then SPL also offers a RecursiveIteratorIterator that taks a RecursiveIterator...so it is just a foreach-four-liner. $text = ''; forach(new RecursiveIteratorIterator($sxe) as $el) { $text .= $el; }
>> So i'd say let us add a method for returning the complete content. Adam >> could you do that?
> That wouldn't be too difficult (although I am busy for the next day or > two). However, as much as I loathe toggles, I'm wondering if it > wouldn't be better to make this an object-wide setting. My thought are > that on an object-by-object basis, you either always want tags or > never want them.
> Something like:
> $sxe = simplexml_load_file('doc.xml'); > $sxe->displayTags = true;
> This would keep the interface clean. Or would that just confuse things > with more magic?
> Also, what would the default behavior should be? I can argue both > sides of the issue right now. :)
The idea is really nice but you mentioned the problems yourself it is increasing the wtf factor. Maybe we implement both getContent and getText and do this kind of magic in the next version aka 5.1?
-- Best regards, Marcus mailto:helly@php.net

Blake Schwendiman

22 years ago
BTW, I can send my source implementation of my toString() method which returns the full content. Then you can do what you need in terms of renaming, etc. Thanks! Blake Schwendiman ----- Original Message ----- From: "Adam Maccabee Trachtenberg" <adam@trachtenberg.com> To: "Marcus Boerger" <helly@php.net> Cc: "Blake Schwendiman" <blake@mediafence.com>; <internals@lists.php.net> Sent: Wednesday, January 07, 2004 4:59 PM Subject: Re: [PHP-DEV] SimpleXML and Default Cast To String
> On Thu, 8 Jan 2004, Marcus Boerger wrote: > > > From my opinion the current behavior is perfect because i see simplexml
from
> > an xml developers side and not from an html developers side. The former
must
> > typically know exactly where his strings comme from while the latter has > > only text to deal with and often has situations where he needs to filter
out

Adam Maccabee Trachtenberg

22 years ago
Would be glad for the code, send it me as an attachment cause the list can be finicky. :) (Or in other words, it needs to be plain text and end in .txt.) -adam On Wed, 7 Jan 2004, Blake Schwendiman wrote:
> BTW, I can send my source implementation of my toString() method which > returns the full content. Then you can do what you need in terms of > renaming, etc. > > Thanks! > > Blake Schwendiman > > > ----- Original Message ----- > From: "Adam Maccabee Trachtenberg" <adam@trachtenberg.com> > To: "Marcus Boerger" <helly@php.net> > Cc: "Blake Schwendiman" <blake@mediafence.com>; <internals@lists.php.net> > Sent: Wednesday, January 07, 2004 4:59 PM > Subject: Re: [PHP-DEV] SimpleXML and Default Cast To String > > > > On Thu, 8 Jan 2004, Marcus Boerger wrote: > > > > > From my opinion the current behavior is perfect because i see simplexml > from > > > an xml developers side and not from an html developers side. The former > must > > > typically know exactly where his strings comme from while the latter has > > > only text to deal with and often has situations where he needs to filter > out > > > formatting tags like the <i> in the example. > > > > All of my SimpleXML work is strictly XML, too. However, my thought was > > that I could always call strip_tags() to eliminate the information I > > didn't want, but there was no apply_tags() function to do the > > reverse. :) Therefore, it was better to use the other method. > > > > > So i'd say let us add a method for returning the complete content. Adam > > > could you do that? > > > > That wouldn't be too difficult (although I am busy for the next day or > > two). However, as much as I loathe toggles, I'm wondering if it > > wouldn't be better to make this an object-wide setting. My thought are > > that on an object-by-object basis, you either always want tags or > > never want them. > > > > Something like: > > > > $sxe = simplexml_load_file('doc.xml'); > > $sxe->displayTags = true; > > > > This would keep the interface clean. Or would that just confuse things > > with more magic? > > > > Also, what would the default behavior should be? I can argue both > > sides of the issue right now. :) > > > > -adam > > > > -- > > adam@trachtenberg.com > > > >
-- adam@trachtenberg.com author of o'reilly's php cookbook avoid the holiday rush, buy your copy today!

Andi Gutmans

22 years ago
At 06:59 PM 1/7/2004 -0500, Adam Maccabee Trachtenberg wrote:
> > So i'd say let us add a method for returning the complete content. Adam > > could you do that? > >That wouldn't be too difficult (although I am busy for the next day or >two). However, as much as I loathe toggles, I'm wondering if it >wouldn't be better to make this an object-wide setting. My thought are >that on an object-by-object basis, you either always want tags or >never want them. > >Something like: > >$sxe = simplexml_load_file('doc.xml'); >$sxe->displayTags = true; > >This would keep the interface clean. Or would that just confuse things >with more magic?
If anything then displayTags() should be a method so that it doesn't get ambiguous with accessing XML fields.
>Also, what would the default behavior should be? I can argue both >sides of the issue right now. :)
I agree. It's definitely confusing and both sides could be argued. I think I lean towards today's implementation. It does seem to be more in-line with XML and it's structure. I'd keep things the way they are today. Andi

Adam Maccabee Trachtenberg

22 years ago
On Thu, 8 Jan 2004, Andi Gutmans wrote:
> At 06:59 PM 1/7/2004 -0500, Adam Maccabee Trachtenberg wrote: > > > So i'd say let us add a method for returning the complete content. Adam > > > could you do that? > > > >That wouldn't be too difficult (although I am busy for the next day or > >two). However, as much as I loathe toggles, I'm wondering if it > >wouldn't be better to make this an object-wide setting. My thought are > >that on an object-by-object basis, you either always want tags or > >never want them.
[snip]
> I'd keep things the way they are today.
I've spent a little time looking at the code and I realize I misunderstood what was going on. Right now, given this XML: <foo> A<b>B</b>C </foo> Doing a "print $xml;" prints "AC". I think we should be printing "ABC". Doesn't this make more sense? I don't mind eliminating the tags, but we also kill the text node children and that doesn't seem what I'd expect. The second issue is how do we allow people to get the string with tags, or "A<b>B</b>C"? (This is what I thought we were talking about.) For that, I think the best method is to modify to_xml_string() and to_xml_file(). Right now, we serialize the entire document regardless where in the document these methods are called. Instead, I say these methods should just serialize from the current location on down. So, this: print $xml->b->to_xml_string(); Prints this: <b>B</b> I've whipped up a patch that does this: http://www.trachtenberg.com/patches/simplexml_toxmlstring_patch.txt Comments? -adam
-- adam@trachtenberg.com author of o'reilly's php cookbook avoid the holiday rush, buy your copy today!

Blake Schwendiman

22 years ago
The patch you propose is exactly the type of functionality that I was hoping to find. Thank you, Blake Schwendiman -----Original Message----- From: Adam Maccabee Trachtenberg [mailto:adam@trachtenberg.com] Sent: Sunday, January 11, 2004 11:54 PM To: Andi Gutmans Cc: Marcus Boerger; Blake Schwendiman; internals@lists.php.net Subject: Re: [PHP-DEV] SimpleXML and Default Cast To String On Thu, 8 Jan 2004, Andi Gutmans wrote:
> At 06:59 PM 1/7/2004 -0500, Adam Maccabee Trachtenberg wrote: > > > So i'd say let us add a method for returning the complete content.
Adam
> > > could you do that? > > > >That wouldn't be too difficult (although I am busy for the next day
or
> >two). However, as much as I loathe toggles, I'm wondering if it > >wouldn't be better to make this an object-wide setting. My thought
are
> >that on an object-by-object basis, you either always want tags or > >never want them.
[snip]
> I'd keep things the way they are today.
I've spent a little time looking at the code and I realize I misunderstood what was going on. Right now, given this XML: <foo> A<b>B</b>C </foo> Doing a "print $xml;" prints "AC". I think we should be printing "ABC". Doesn't this make more sense? I don't mind eliminating the tags, but we also kill the text node children and that doesn't seem what I'd expect. The second issue is how do we allow people to get the string with tags, or "A<b>B</b>C"? (This is what I thought we were talking about.) For that, I think the best method is to modify to_xml_string() and to_xml_file(). Right now, we serialize the entire document regardless where in the document these methods are called. Instead, I say these methods should just serialize from the current location on down. So, this: print $xml->b->to_xml_string(); Prints this: <b>B</b> I've whipped up a patch that does this: http://www.trachtenberg.com/patches/simplexml_toxmlstring_patch.txt Comments? -adam
-- adam@trachtenberg.com author of o'reilly's php cookbook avoid the holiday rush, buy your copy today! -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php

Sterling Hughes

22 years ago
The idea of simplexml is to return the nodes of *that particular node*, not all of the subsequent nodes, therefore (as mentioned before), the current behaviour is correct. The current behaviour of to_xml_string() is however, wrong. It should return the xml content from the current node as adam points out. The current behaviour of to_xml_file() is appropriate, but inconsistent (as adam's patch points out). to_xml_string() and to_xml_file() are both rather confusing names as well. My thoughts on this are as follows, some are directly related to the topic, some are related to simplexml's original design and current functionality. SimpleXML was originally designed to provide a direct mapping between a XML document and a data structure, through access to the properties and attributes and *only* the properties and attributes. Much of the current code in SimpleXML is due to immaturities in either Zend or the LibXML interface at the time I was writing SimpleXML. I wanted to have cool things to show at conferences, plus other people wanted to see what was possible with simplexml, so features started to creep in. xsearch() and schema validation were the first added, then came other methods like hasChildren() and getChildren() (when a simple xpath query /child::node() can tell you this) Most of simplexml's methods are either redundant, or redundant based upon redundancy (hasChildren(), getChildren(), attributes(), count()). Each of these methods are actually a very simple, very optimized xpath expression. I know its late in the process, but its also the last chance for an API change, or rather adjustment, the change was always meant to happen, I just got a bit too busy to do it. So here are my thoughts on an API: 1) Remove all methods from simplexml. They were never supposed to be permanent parts of the API. 2) Add three new functions: simplexml_register_ns(simplexml_element $e, string name, string value) simplexml_save_file(simplexml_element $e, string filename) simplexml_save_string(simplexml_element $e, string &$data) The last two functions will work as Adam mentions, saving from the current node. The copy of the data can be omitted, since libxml2 should be using our memory management functions. 3) For the next version of PHP, PHP5.1 add a new xpath extension which provides a generic query interface to XML objects. This would be something like: if (xpath_query('/child::node()', $node, $results)) { } As xpath is very much akin to regular expressions for XML. This is a more elegant solution than the current DOM api for XML which would require a casting into a dom object, then a domxpath object, then a simplexml object. (*) I realize this is a rather drastic change so late in the game. But this was the original intent of the extension, and indeed is more consistent than the current solution. I also think that the current direction with these helper methods is wrong. They don't help, they just muddy the waters up. As a further note. SimpleXML is not currently ready for production usage, I've been going through it over the past couple of days, and it needs some work (especially since some bugs in Zend currently make things impossible). I'm loth to do a deep grotting of the extension (even though its easier now that we have a test suite), but quite a bit can be won in terms of consistency and stability (code path) - I think this should be a part of that work, and I would be willing to make the necessary changes. Anyhow, these are my thoughts on the matter. -Sterling (*) The DOM api could be left for PHP5.0, but shouldn't be the only option. The xpath extension would actually be quite trivial, and could be done quickly. Most of the code is already in DOM and SimpleXML, it would just be moving it to a separate extension.

Adam Maccabee Trachtenberg

22 years ago
On Mon, 12 Jan 2004, Sterling Hughes wrote:
> The idea of simplexml is to return the nodes of *that particular node*, > not all of the subsequent nodes, therefore (as mentioned before), the > current behaviour is correct.
I yield to popular opinion and voice of the original author. :)
> The current behaviour of to_xml_string() is however, wrong. It should > return the xml content from the current node as adam points out. The > current behaviour of to_xml_file() is appropriate, but inconsistent > (as adam's patch points out). to_xml_string() and to_xml_file() are > both rather confusing names as well.
I've also never liked those names either, but it seemed bad form to request changes in the API.
> My thoughts on this are as follows, some are directly related to the topic, > some are related to simplexml's original design and current functionality. > SimpleXML was originally designed to provide a direct mapping between a > XML document and a data structure, through access to the properties and > attributes and *only* the properties and attributes.
I am in strong agreement here.
> Much of the current code in SimpleXML is due to immaturities in either > Zend or the LibXML interface at the time I was writing SimpleXML. I wanted > to have cool things to show at conferences, plus other people wanted to see > what was possible with simplexml, so features started to creep in. xsearch() > and schema validation were the first added, then came other methods like > hasChildren() and getChildren() (when a simple xpath query /child::node() can > tell you this) > > Most of simplexml's methods are either redundant, or redundant based > upon redundancy (hasChildren(), getChildren(), attributes(), count()). > Each of these methods are actually a very simple, very optimized xpath > expression.
The only SimpleXML methods (besides the ones for getting data in and out of the object) I care about are xquery and validation. I've never used (or really even known about) the other ones and don't see a need for them.
> I know its late in the process, but its also the last chance for an API > change, or rather adjustment, the change was always meant to happen, I > just got a bit too busy to do it. So here are my thoughts on an API: > > 1) Remove all methods from simplexml. They were never supposed to be > permanent parts of the API. > > 2) Add three new functions: > > simplexml_register_ns(simplexml_element $e, string name, string value) > simplexml_save_file(simplexml_element $e, string filename) > simplexml_save_string(simplexml_element $e, string &$data)
simplexml_save_dom(simplexml_element $e, domDocument $dom)
> > The last two functions will work as Adam mentions, saving from the current > node. The copy of the data can be omitted, since libxml2 should be > using our memory management functions.
I prefer it when functions that create strings and objects return them, so I vote for: string simplexml_save_string(simplexml_element $e) I want to be able to do: if ($data = simplexml_save_string($e)) { print $data; } The preg() functions have an API like yours and I hate it. They always require an extra step to extract the data from the $results array.
> 3) For the next version of PHP, PHP5.1 add a new xpath extension which > provides a generic query interface to XML objects. This would be > something like: > > if (xpath_query('/child::node()', $node, $results)) { > } > > As xpath is very much akin to regular expressions for XML. This is a > more elegant solution than the current DOM api for XML which would > require a casting into a dom object, then a domxpath object, then a > simplexml object. (*)
If you're going to blow things up, I would much prefer that you somehow manage to get this into PHP 5.0. Right now, AFAIK, xsearch() is the only way to do any XML Namespace querying and casting things through that chain of objects causes me to barf more than even XML Namespaces. :) And, as you say below, this code already exists in xsearch(), it's just a matter of figuring out where to put it. Why not just do: array simplexml_xpath_query(simplexml_element $e, string $xpath) This allows for: foreach(simplexml_xpath_query($node, '//foo') as $foo) { print $foo; } DOM is explicitly an OO API. You seem to want SimpleXML to be procedural. (I must admit here that I actually like the SimpleXML OO API.) Therefore, I think it makes sense for domXPath to continue to be an OO solution for DOM and just build in an procedural XPath function into the SimpleXML extension.
> I realize this is a rather drastic change so late in the game. > But this was the original intent of the extension, and indeed is more consistent > than the current solution. I also think that the current direction with > these helper methods is wrong. They don't help, they just muddy the > waters up. > > As a further note. SimpleXML is not currently ready for production > usage, I've been going through it over the past couple of days, and it > needs some work (especially since some bugs in Zend currently make > things impossible). I'm loth to do a deep grotting of the extension > (even though its easier now that we have a test suite), but quite a bit can be won > in terms of consistency and stability (code path) - I think this should > be a part of that work, and I would be willing to make the necessary > changes.
I'm about to put it into production use, so we'll see about that. I will be using it as a CGI, however, so leaks aren't a problem. :) We've also never discussed the infamous scalar versus array issue you promised me you'd fix at ApacheCon: if (is_array($e->foo)) { $foo = join(',', $e->foo); } else { $foo = $e->foo; } I think this opens a whole 'nother can of worms, but if you're looking to clean things up, now's the right time. :) I caused quite a ruckus with my request for autocasting to a string. I'm interested in seeing how this one gets resolved. Seriously, the code above is a bit of a kludge, but totally workable. I would be willing to help out here as I've spent a bunch of time hanging about the libxml2 API already while trying to fix PHP 5 XML issues. -adam
-- adam@trachtenberg.com author of o'reilly's php cookbook avoid the holiday rush, buy your copy today!

Sterling Hughes

22 years ago
> > Much of the current code in SimpleXML is due to immaturities in either > > Zend or the LibXML interface at the time I was writing SimpleXML. I wanted > > to have cool things to show at conferences, plus other people wanted to see > > what was possible with simplexml, so features started to creep in. xsearch() > > and schema validation were the first added, then came other methods like > > hasChildren() and getChildren() (when a simple xpath query /child::node() can > > tell you this) > > > > Most of simplexml's methods are either redundant, or redundant based > > upon redundancy (hasChildren(), getChildren(), attributes(), count()). > > Each of these methods are actually a very simple, very optimized xpath > > expression. > > The only SimpleXML methods (besides the ones for getting data in and > out of the object) I care about are xquery and validation. I've never > used (or really even known about) the other ones and don't see a need > for them. >
Ahh, i missed validation. See notes below.
> > I know its late in the process, but its also the last chance for an API > > change, or rather adjustment, the change was always meant to happen, I > > just got a bit too busy to do it. So here are my thoughts on an API: > > > > 1) Remove all methods from simplexml. They were never supposed to be > > permanent parts of the API. > > > > 2) Add three new functions: > > > > simplexml_register_ns(simplexml_element $e, string name, string value) > > simplexml_save_file(simplexml_element $e, string filename) > > simplexml_save_string(simplexml_element $e, string &$data) > > simplexml_save_dom(simplexml_element $e, domDocument $dom) >
dom has a function to do this.
> > > > The last two functions will work as Adam mentions, saving from the current > > node. The copy of the data can be omitted, since libxml2 should be > > using our memory management functions. > > I prefer it when functions that create strings and objects return > them, so I vote for: > > string simplexml_save_string(simplexml_element $e) > > I want to be able to do: > > if ($data = simplexml_save_string($e)) { > print $data; > } > > The preg() functions have an API like yours and I hate it. They always > require an extra step to extract the data from the $results array. >
Yeah, I had it the other way for consistency but would be willing to yield to popular opinion. ;)
> > 3) For the next version of PHP, PHP5.1 add a new xpath extension which > > provides a generic query interface to XML objects. This would be > > something like: > > > > if (xpath_query('/child::node()', $node, $results)) { > > } > > > > As xpath is very much akin to regular expressions for XML. This is a > > more elegant solution than the current DOM api for XML which would > > require a casting into a dom object, then a domxpath object, then a > > simplexml object. (*) > > If you're going to blow things up, I would much prefer that you > somehow manage to get this into PHP 5.0. Right now, AFAIK, xsearch() > is the only way to do any XML Namespace querying and casting things > through that chain of objects causes me to barf more than even XML > Namespaces. :) > > And, as you say below, this code already exists in xsearch(), it's > just a matter of figuring out where to put it. Why not just do: > > array simplexml_xpath_query(simplexml_element $e, string $xpath) > > This allows for: > > foreach(simplexml_xpath_query($node, '//foo') as $foo) { > print $foo; > } > > DOM is explicitly an OO API. You seem to want SimpleXML to be > procedural. (I must admit here that I actually like the SimpleXML OO > API.) > > Therefore, I think it makes sense for domXPath to continue to be an OO > solution for DOM and just build in an procedural XPath function into > the SimpleXML extension.
Well, that's certainly an option. Whilst I prefer to have standard api's for this across PHP, I'm not terribly adamant about this particular issue. The main idea would be to have a standard schema interface and a standard xpath interface that would work perfectly with both DOM and SimpleXML objects, in fact the two would be interchangeable because they are both libxml objects underneath. I think that would be sexy, but I'm willing to give it up. The problem with simplexml_xpath_query returning an array is that how do you signify failure and an empty set. In order for you to have code that uses foreach() it would need to return an empty set on failure in order to avoid warnings. The reason that there is an extra argument (as with PCRE) is for the failure condition.
> > > I realize this is a rather drastic change so late in the game. > > But this was the original intent of the extension, and indeed is more consistent > > than the current solution. I also think that the current direction with > > these helper methods is wrong. They don't help, they just muddy the > > waters up. > > > > As a further note. SimpleXML is not currently ready for production > > usage, I've been going through it over the past couple of days, and it > > needs some work (especially since some bugs in Zend currently make > > things impossible). I'm loth to do a deep grotting of the extension > > (even though its easier now that we have a test suite), but quite a bit can be won > > in terms of consistency and stability (code path) - I think this should > > be a part of that work, and I would be willing to make the necessary > > changes. > > I'm about to put it into production use, so we'll see about that. I > will be using it as a CGI, however, so leaks aren't a problem. :) >
:) It doesn't have too many leaks, its just terribly inconsistent underneath. It also has some crashes when you reach edge cases. Partially due to Zend, partially due to some sloppy coding.
> We've also never discussed the infamous scalar versus array issue you > promised me you'd fix at ApacheCon: > > if (is_array($e->foo)) { > $foo = join(',', $e->foo); > } else { > $foo = $e->foo; > } > > I think this opens a whole 'nother can of worms, but if you're looking > to clean things up, now's the right time. :) I caused quite a ruckus > with my request for autocasting to a string. I'm interested in seeing > how this one gets resolved. Seriously, the code above is a bit of a > kludge, but totally workable.
I'll look at this today.
> > I would be willing to help out here as I've spent a bunch of time > hanging about the libxml2 API already while trying to fix PHP 5 XML > issues.
I'm happy for any help. But I want to make sure to open this up to disagreement before we go ahead and start fixing things. -Sterling

Adam Maccabee Trachtenberg

22 years ago
On Mon, 12 Jan 2004, Sterling Hughes wrote: [snip]
> > simplexml_save_dom(simplexml_element $e, domDocument $dom) > > > > dom has a function to do this.
I guess it doesn't make too much difference whether DOM imports a SimpleXML object or SimpleXML exports a DOM object to me. [snip]
> > > 3) For the next version of PHP, PHP5.1 add a new xpath extension which > > > provides a generic query interface to XML objects. This would be > > > something like: > > > > > > if (xpath_query('/child::node()', $node, $results)) { > > > } > > > > > > As xpath is very much akin to regular expressions for XML. This is a > > > more elegant solution than the current DOM api for XML which would > > > require a casting into a dom object, then a domxpath object, then a > > > simplexml object. (*) > > > > If you're going to blow things up, I would much prefer that you > > somehow manage to get this into PHP 5.0. Right now, AFAIK, xsearch() > > is the only way to do any XML Namespace querying and casting things > > through that chain of objects causes me to barf more than even XML > > Namespaces. :) > > > > And, as you say below, this code already exists in xsearch(), it's > > just a matter of figuring out where to put it. Why not just do: > > > > array simplexml_xpath_query(simplexml_element $e, string $xpath) > > > > This allows for: > > > > foreach(simplexml_xpath_query($node, '//foo') as $foo) { > > print $foo; > > } > > > > DOM is explicitly an OO API. You seem to want SimpleXML to be > > procedural. (I must admit here that I actually like the SimpleXML OO > > API.) > > > > Therefore, I think it makes sense for domXPath to continue to be an OO > > solution for DOM and just build in an procedural XPath function into > > the SimpleXML extension. > > Well, that's certainly an option. Whilst I prefer to have standard > api's for this across PHP, I'm not terribly adamant about this > particular issue. The main idea would be to have a standard schema > interface and a standard xpath interface that would work perfectly with > both DOM and SimpleXML objects, in fact the two would be interchangeable > because they are both libxml objects underneath. I think that would be > sexy, but I'm willing to give it up.
Well, domXPath::query() now returns a DOM-style nodeList object instead of an array. This is consistent with DOM's getElementsByTagName() method, but different from SimpleXML's array-based approach. One solution could be to vary the return types based upon the input type (arrays for SimpleXML, nodeLists for DOM), but that doesn't seem like a wise decision to me. I'm open to other options. In theory, I like the idea of a unified set of XML helper extensions, but DOM's so big and ugly that I don't know if it plays well with others in the sandbox. Rob will probably have an opinion here, I'm sure.
> The problem with simplexml_xpath_query returning an array is that how do > you signify failure and an empty set. In order for you to have code > that uses foreach() it would need to return an empty set on failure in > order to avoid warnings. The reason that there is an extra argument (as > with PCRE) is for the failure condition.
I know, I'm just a sloppy coder... [snip]
> > We've also never discussed the infamous scalar versus array issue you > > promised me you'd fix at ApacheCon: > > > > if (is_array($e->foo)) { > > $foo = join(',', $e->foo); > > } else { > > $foo = $e->foo; > > } > > > > I think this opens a whole 'nother can of worms, but if you're looking > > to clean things up, now's the right time. :) I caused quite a ruckus > > with my request for autocasting to a string. I'm interested in seeing > > how this one gets resolved. Seriously, the code above is a bit of a > > kludge, but totally workable. > > I'll look at this today.
Thanks. Like I said, it's a bit of a pain, but nothing killer.
> > I would be willing to help out here as I've spent a bunch of time > > hanging about the libxml2 API already while trying to fix PHP 5 XML > > issues. > > I'm happy for any help. But I want to make sure to open this up to > disagreement before we go ahead and start fixing things.
Ditto. -adam
-- adam@trachtenberg.com author of o'reilly's php cookbook avoid the holiday rush, buy your copy today!

Christian Schneider

22 years ago
Sterling Hughes wrote:
> The problem with simplexml_xpath_query returning an array is that how do > you signify failure and an empty set. In order for you to have code > that uses foreach() it would need to return an empty set on failure in > order to avoid warnings.
My preferred solution would be 1) return an array (including empty array for empty result set) 2) return null for error. This way one can distinguish between error and empty result set if needed and cast to array if it doesn't matter, e.g. for foreach. To me null is the natural way of signalling an invalid value, see also NULL in SQL. - Chris

Rob Richards

22 years ago
> My thoughts on this are as follows, some are directly related to the
topic,
> some are related to simplexml's original design and current functionality. > SimpleXML was originally designed to provide a direct mapping between a > XML document and a data structure, through access to the properties and > attributes and *only* the properties and attributes.
What's the ultimate goal for simpleXML? I have been hesitant from ever touching this extension as what I thought it was intended to do, seems simplistic to where it acutally (is going/went?). Correct me if I'm wrong, but when it started I thought simpleXML's intent was to handle XML structures containing only elements and attributes (or at least ignoring everything else). The structure could never contain an element which had an attribute named the same as one of its child elements (otherwise you would need to be adding functionality as well to distinguish when you work with the attribute or element). Also, elements would contain either text or children elements but not both. Not sure about how adding one of these types was to be handled as you would need a way to determine wether you are adding an element or an attribute. As I said, this may be a simplistic view, but as it evolved, I just dont understand the concept behind simpleXML anymore.
> 3) For the next version of PHP, PHP5.1 add a new xpath extension which > provides a generic query interface to XML objects. This would be > something like: > > if (xpath_query('/child::node()', $node, $results)) { > } > > As xpath is very much akin to regular expressions for XML. This is a > more elegant solution than the current DOM api for XML which would > require a casting into a dom object, then a domxpath object, then a > simplexml object. (*)
There is a problem here however as simpleXML can only handle Element, Attribute and Text nodes, so if any other node type is returned in the nodelist there will be problems. simpleXML will need a custom xpath handler to insure that the returned nodes are of type element or attribute. The dom api for xpath also wasnt meant as the end all solution either. It was a quick implementation to at least support querying nodes in the document, but thats about all it does. The majority of XPath functionality wasnt touched. I do agree with the comment that DOM is big and clunky. In reality, I have only ever had to use a handful of its functions and the only reason it got done is that people using domxml wanted a compliant implementation that implemented the functionality correctly and I had time to kill. Personally I would like a simpleXML/DOM hybrid extension which took some of the best features of each, so would offer the ease of use of simpleXML, some of the more advanced features/methods in dom, yet noy have all the dom api baggage. Rob

Sterling Hughes

22 years ago
> > My thoughts on this are as follows, some are directly related to the > topic, > > some are related to simplexml's original design and current functionality. > > SimpleXML was originally designed to provide a direct mapping between a > > XML document and a data structure, through access to the properties and > > attributes and *only* the properties and attributes. > > What's the ultimate goal for simpleXML? I have been hesitant from ever > touching this extension as what I thought it was intended to do, seems > simplistic to where it acutally (is going/went?). Correct me if I'm wrong, > but when it started I thought simpleXML's intent was to handle XML > structures containing only elements and attributes (or at least ignoring > everything else). The structure could never contain an element which had an > attribute named the same as one of its child elements (otherwise you would > need to be adding functionality as well to distinguish when you work with > the attribute or element). Also, elements would contain either text or > children elements but not both. >
Now that Zend can differentiate between array accessors and property accesses, attributes and nodes should be separated. As for the second, yes, that's true, although xpath expressions could achieve this.
> Not sure about how adding one of these types was to be handled as you would > need a way to determine wether you are adding an element or an attribute. > > As I said, this may be a simplistic view, but as it evolved, I just dont > understand the concept behind simpleXML anymore. > > > 3) For the next version of PHP, PHP5.1 add a new xpath extension which > > provides a generic query interface to XML objects. This would be > > something like: > > > > if (xpath_query('/child::node()', $node, $results)) { > > } > > > > As xpath is very much akin to regular expressions for XML. This is a > > more elegant solution than the current DOM api for XML which would > > require a casting into a dom object, then a domxpath object, then a > > simplexml object. (*) > > There is a problem here however as simpleXML can only handle Element, > Attribute and Text nodes, so if any other node type is returned in the > nodelist there will be problems. simpleXML will need a custom xpath handler > to insure that the returned nodes are of type element or attribute. > > The dom api for xpath also wasnt meant as the end all solution either. It > was a quick implementation to at least support querying nodes in the > document, but thats about all it does. The majority of XPath functionality > wasnt touched. > > I do agree with the comment that DOM is big and clunky. In reality, I have > only ever had to use a handful of its functions and the only reason it got > done is that people using domxml wanted a compliant implementation that > implemented the functionality correctly and I had time to kill. Personally I > would like a simpleXML/DOM hybrid extension which took some of the best > features of each, so would offer the ease of use of simpleXML, some of the > more advanced features/methods in dom, yet noy have all the dom api baggage. >
Well, this can be added with userspace handlers as I mentioned to Marcus. The real trick to XML manipulation is Xpath, not adding a bunch of broken methods. If people want to do that, they can load a simplexml object into DOM, and use the two together. ;) -Sterling

Rob Richards

22 years ago
> Well, this can be added with userspace handlers as I mentioned to > Marcus. The real trick to XML manipulation is Xpath, not adding a bunch > of broken methods. If people want to do that, they can load a simplexml > object into DOM, and use the two together. ;)
XPath cant be the answer to everything. Although it would work, XPath is slow. I dont have them handy, but benchmarking was done for libxml on XPath querying and simplly walking the tree and manuallly performing tests. As the size of the document increased, the time to perform the XPath query went up by drastically comapred to manual processing. This is a good reason to use many of the dom methods over xpath as they are much faster. If speed isnt an issue then its a real moot point. Don't get me wrong, I agree that simpleXML should be simple without alot of those methods (as a majority of the people using xml dont and most likely never will use them). And XPath is the answer for them when they need a little more juice. I can live with the interop between simpleXML and dom I guess, but see I wasnt the only one who was mentioning a happy medium between the 2 :) Rob

Adam Maccabee Trachtenberg

22 years ago
On Mon, 12 Jan 2004, Sterling Hughes wrote:
> > What's the ultimate goal for simpleXML? I have been hesitant from ever > > touching this extension as what I thought it was intended to do, seems > > simplistic to where it acutally (is going/went?). Correct me if I'm wrong, > > but when it started I thought simpleXML's intent was to handle XML > > structures containing only elements and attributes (or at least ignoring > > everything else). The structure could never contain an element which had an > > attribute named the same as one of its child elements (otherwise you would > > need to be adding functionality as well to distinguish when you work with > > the attribute or element). Also, elements would contain either text or > > children elements but not both. > > > > Now that Zend can differentiate between array accessors and property accesses, > attributes and nodes should be separated.
I might be crazy, but they already are. This was changed months ago. I am the only one who actually uses SimpleXML? :) -adam
-- adam@trachtenberg.com author of o'reilly's php cookbook avoid the holiday rush, buy your copy today!

Andi Gutmans

22 years ago
At 01:53 AM 1/12/2004 -0500, Adam Maccabee Trachtenberg wrote:
>On Thu, 8 Jan 2004, Andi Gutmans wrote: > > > At 06:59 PM 1/7/2004 -0500, Adam Maccabee Trachtenberg wrote: > > > > So i'd say let us add a method for returning the complete content. Adam > > > > could you do that? > > > > > >That wouldn't be too difficult (although I am busy for the next day or > > >two). However, as much as I loathe toggles, I'm wondering if it > > >wouldn't be better to make this an object-wide setting. My thought are > > >that on an object-by-object basis, you either always want tags or > > >never want them. > >[snip] > > > I'd keep things the way they are today. > >I've spent a little time looking at the code and I realize I >misunderstood what was going on. Right now, given this XML: > ><foo> > A<b>B</b>C ></foo> > >Doing a "print $xml;" prints "AC". I think we should be printing >"ABC". Doesn't this make more sense? I don't mind eliminating the >tags, but we also kill the text node children and that doesn't seem >what I'd expect.
Actually I think AC makes more sense. the B is in $xml->foo->b
>The second issue is how do we allow people to get the string with >tags, or "A<b>B</b>C"? (This is what I thought we were talking about.) >For that, I think the best method is to modify to_xml_string() and >to_xml_file(). > >Right now, we serialize the entire document regardless where in the >document these methods are called. Instead, I say these methods should >just serialize from the current location on down. So, this: > >print $xml->b->to_xml_string(); > >Prints this: > ><b>B</b> > >I've whipped up a patch that does this: >http://www.trachtenberg.com/patches/simplexml_toxmlstring_patch.txt > >Comments?
I think that might be a nice patch because it encapsulates this service in a method. What do the rest think? Andi