Re: [boost] Re: API Review request: XML API for C++, second round
On Fri, 2003-06-27 at 12:53, Anthony Williams wrote: > It was meant to be a description of semantics, in terms of a sample > implementation. > > A node that is not part of a document is a free-standing subtree that needs > adding to a document. If it is an element, then you can treat it as if it is > the root node of a document. If it is anything else, then you are more limited > in what you can do, but then what does it mean to perform an XPath query on a > PI? > > If the underlying API requires that the document is kept alive to keep the > nodes alive, then the wrapper class must handle this, whilst simulating the > above semantic description. If you look in one of my other posts you will see a description of just that. The thing that concerns me most about this is doc.find( path ).parent(); // non null (unless it found the root node) BUT... node n( doc.find( path ) ); n.parent(); // User may not expect this to be null n.document(); // or this You could have a node_container (or standalone_node) which had no parent or document methods but otherwise looked like a node. node_container n( doc.find( path ) ); n.parent(); // compile time error n.document(); // compile time error which is good but doesn't really solve the problem... n.first_child().document(); // null My preference is that if you want to make a copy of a node you have to have a new document... document doc2( doc.find( path ) ); doc2.root().parent(); // null but you would expect that (it's the root) doc2.root().document(); // non null as you would expect That way the user can rely on parent() to be non null for all but root nodes and document() can return a reference since it can never be null. > > You could copy the libxml2 tree into your own structure but then you are > > on your own when it comes to higher level things like xpath and xslt. > > I imagined that you would write forwarding functions for the underlying API, > so when you are given an Xpath query, you pass it on to the underlying API and > then wrap the result. Then you would need to keep libxml2 version of the tree too and synchronise any changes (or rebuild it every time you want to call a libxml2 function). -- Hamish Mackenzie <[EMAIL PROTECTED]> ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: API Review request: XML API for C++, second round
Anthony Williams wrote: Hmm, just to check whether we are still talking about the same thing here: do we agree that there can't be a 'node' type, i.e. just a 'node_ref'/'node_ptr' ? You mean: have "node" as an abstract class, so you can't have any objects of that type, but you can have pointers and references? Sounds good. What's wrong with just having boost::shared_ptr and boost::shared_ptr, boost::shared_ptr ? no, I was alluding to the fact that in my case nodes are fully managed their parent. That implies that I can't have free floating nodes, i.e. outside the document tree. Well, I probably could but that would put the burden of managing the memory on the programmer's shoulders, while with the current model all memory is managed by libxml2. That's why I'm suggesting _ptr/_ref types in the first place. The expression dom::node_ptr parent = current.parent(); will return a reference to the parent node, i.e. it will create a temporary reference object, who's lifecycle is fully decoupled from the lifecycle of the actual node (who is managed by the document tree). You could have each node store a boost::weak_ptr pointing to its parent, which is converted to a boost::shared_ptr when you ask for it. That way, a child doesn't keep its parent alive (though parents should keep their children alive), but you can still traverse up the tree if you like. yes, when reimplementing a dom tree from scratch that may be an option. But as I said, I'm wrapping a C XML library that already does most of the work for me, and I'm trying to make the wrapper objects as lightweight as possible. Regards, Stefan ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: API Review request: XML API for C++, second round
Hamish Mackenzie <[EMAIL PROTECTED]> writes: > On Fri, 2003-06-27 at 09:09, Anthony Williams wrote: > > What's wrong with just having boost::shared_ptr and > > boost::shared_ptr, boost::shared_ptr ? > > > > You could have each node store a boost::weak_ptr pointing to its > > parent, which is converted to a boost::shared_ptr when you ask for > > it. That way, a child doesn't keep its parent alive (though parents should > > keep their children alive), but you can still traverse up the tree if you > > like. > > > > You could do the same for documents --- the document holds a shared_ptr to > > the root element, and so keeps the whole tree alive. Each element holds a > > weak_ptr to the document, so you can retrieve the document from it, but it > > doesn't keep it alive. Consequently, if you erase an element from the > > document, but you still have a pointer to it, then the element itself is > > OK, but it will then die when your pointer goes out of scope. Also, if the > > document goes out of scope, then your element is still OK, but is no > > longer associated with a document. > > This sounds like a description of an implementation rather than the > interface. This implementation would not solve the problem "what is a > node when it is not part of document?". It was meant to be a description of semantics, in terms of a sample implementation. A node that is not part of a document is a free-standing subtree that needs adding to a document. If it is an element, then you can treat it as if it is the root node of a document. If it is anything else, then you are more limited in what you can do, but then what does it mean to perform an XPath query on a PI? If the underlying API requires that the document is kept alive to keep the nodes alive, then the wrapper class must handle this, whilst simulating the above semantic description. > Your implementation would be much easier to wrap than libxml2. You > could implement the same interface simply with... > > typedef Document document; > typedef Node * node_ptr; > typedef Node & node_ref; > > The problem when wrapping libxml2 is that the node is stored by libxml2 > in its own xmlNode structure. You can't add methods to it like you > could if you wrote your own Node. > > You could copy the libxml2 tree into your own structure but then you are > on your own when it comes to higher level things like xpath and xslt. I imagined that you would write forwarding functions for the underlying API, so when you are given an Xpath query, you pass it on to the underlying API and then wrap the result. Anthony -- Anthony Williams Senior Software Engineer, Beran Instruments Ltd. Remove NOSPAM when replying, for timely response. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: API Review request: XML API for C++, second round
On Fri, 2003-06-27 at 09:09, Anthony Williams wrote: > Stefan Seefeld <[EMAIL PROTECTED]> writes: > > > Hamish Mackenzie wrote: > > > > > dom::document doc; > > > dom::document_ref doc2( doc.root().document() ); > > > assert( &doc2 == &doc ); > > > and... > > > assert( doc2 == doc ); > > > Can be implemented but ideally it would compare all the nodes in the > > > document. > > > > well, that's different. Do you want to know whether both documents are > > equal, or whether they are identical, i.e. whether both references point to > > the same document ? > > > > Hmm, just to check whether we are still talking about the same thing here: > > do we agree that there can't be a 'node' type, i.e. just a > > 'node_ref'/'node_ptr' ? > > You mean: have "node" as an abstract class, so you can't have any objects of > that type, but you can have pointers and references? Sounds good. > > What's wrong with just having boost::shared_ptr and > boost::shared_ptr, boost::shared_ptr ? > > You could have each node store a boost::weak_ptr pointing to its > parent, which is converted to a boost::shared_ptr when you ask for > it. That way, a child doesn't keep its parent alive (though parents should > keep their children alive), but you can still traverse up the tree if you > like. > > You could do the same for documents --- the document holds a shared_ptr to the > root element, and so keeps the whole tree alive. Each element holds a weak_ptr > to the document, so you can retrieve the document from it, but it doesn't keep > it alive. Consequently, if you erase an element from the document, but you > still have a pointer to it, then the element itself is OK, but it will then > die when your pointer goes out of scope. Also, if the document goes out of > scope, then your element is still OK, but is no longer associated with a > document. This sounds like a description of an implementation rather than the interface. This implementation would not solve the problem "what is a node when it is not part of document?". Your implementation would be much easier to wrap than libxml2. You could implement the same interface simply with... typedef Document document; typedef Node * node_ptr; typedef Node & node_ref; The problem when wrapping libxml2 is that the node is stored by libxml2 in its own xmlNode structure. You can't add methods to it like you could if you wrote your own Node. You could copy the libxml2 tree into your own structure but then you are on your own when it comes to higher level things like xpath and xslt. -- Hamish Mackenzie <[EMAIL PROTECTED]> ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: API Review request: XML API for C++, second round
Stefan Seefeld <[EMAIL PROTECTED]> writes: > Hamish Mackenzie wrote: > > > dom::document doc; > > dom::document_ref doc2( doc.root().document() ); > > assert( &doc2 == &doc ); > > and... > > assert( doc2 == doc ); > > Can be implemented but ideally it would compare all the nodes in the > > document. > > well, that's different. Do you want to know whether both documents are > equal, or whether they are identical, i.e. whether both references point to > the same document ? > > Hmm, just to check whether we are still talking about the same thing here: > do we agree that there can't be a 'node' type, i.e. just a > 'node_ref'/'node_ptr' ? You mean: have "node" as an abstract class, so you can't have any objects of that type, but you can have pointers and references? Sounds good. What's wrong with just having boost::shared_ptr and boost::shared_ptr, boost::shared_ptr ? You could have each node store a boost::weak_ptr pointing to its parent, which is converted to a boost::shared_ptr when you ask for it. That way, a child doesn't keep its parent alive (though parents should keep their children alive), but you can still traverse up the tree if you like. You could do the same for documents --- the document holds a shared_ptr to the root element, and so keeps the whole tree alive. Each element holds a weak_ptr to the document, so you can retrieve the document from it, but it doesn't keep it alive. Consequently, if you erase an element from the document, but you still have a pointer to it, then the element itself is OK, but it will then die when your pointer goes out of scope. Also, if the document goes out of scope, then your element is still OK, but is no longer associated with a document. Anthony -- Anthony Williams Senior Software Engineer, Beran Instruments Ltd. Remove NOSPAM when replying, for timely response. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: API Review request: XML API for C++, second round
Hi Bohdan, even though you may think of a dom tree as 'just another tree', there is really quite a bit of domain-specific semantics associated with it that makes it impractical to use a general-purpose tree/graph library as the underlying representation. To get an idea of what these xml-specific features are, you may look into the code of libxml2. They do quite a lot of work which you may be unaware of until you really need it. Regards, Stefan ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: API Review request: XML API for C++, second round
Hi, Some time ago there was tree-container proposal and if i don't mind there is one in files section or in sandbox. During this discussion someone mentioned that same interface can be used for xml document ... Just curious if it is good idea ? Or it is unusable for heterogenous xml (libxml2) objects like nodes,attributes, text .. ? IMHO i like libraries which manual first lines contain ".. Xxx library/class has the same interface as Yyy library/class ... ". regards, bohdan ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost