// Copyright (c) 2002 David Muse // See the COPYING file for more information. #ifndef RUDIMENTS_XMLDOMNODE_H #define RUDIMENTS_XMLDOMNODE_H #include <rudiments/private/xmldomnodeincludes.h> // The xmldomnode class provides a generic container for DOM tree elements. // One can navigate the nodes of the tree, modify the tree and read or modify // the data that the nodes contain by calling methods in this class. // // A DOM tree node can be one of the following: // the document root // a tag // a tag attribute // a segment of text // a comment // a segment of CDATA // // Each node may contain the following data, though for some node types, the // data container is unused: // type // name // value // parent node // next sibling // previous sibling // a list of attribute nodes // a list of child nodes // // Here is a breakdown by node type: // // For the document root: // type - ROOT_XMLDOMNODETYPE // name - "document" // value - unused // parent node - unused // next sibling - unused // previous sibling - unused // a list of attribute nodes - unused // a list of child nodes - the xml version tag, the doctype tag // and the top-level enclosing tag // // For a tag: // type - TAG_XMLDOMNODETYPE // name - the tag name // value - unused // parent node - the parent tag or document root // next sibling - can be another tag, a segment of text, // a comment or a segment of cdata // previous sibling - can be another tag, a segment of text, // a comment or a segment of cdata // a list of attribute nodes - a list of attribute nodes // a list of child nodes - a list of tags, text segments, comments // and/or cdata segments // // For a tag attribute: // type - ATTRIBUTE_XMLDOMNODETYPE // name - the attribute name // value - the attribute value // (note that for tags with standalone // attributes, the name and value are the same) // parent node - the tag containing the attributes // next sibling - the next attribute // previous sibling - the previous attribute // a list of attribute nodes - unused // a list of child nodes - unused // // For a segment of text: // type - TEXT_XMLDOMNODETYPE // name - "text" // value - the text itself // parent node - the tag containing the text // next sibling - can be a tag, a comment or a segment of cdata // previous sibling - can be a tag, a comment or a segment of cdata // a list of attribute nodes - unused // a list of child nodes - unused // // For a comment: // type - COMMENT_XMLDOMNODETYPE // name - "comment" // value - the comment itself // parent node - the tag containing the comment // next sibling - can be a tag, a segment of text, another // comment or a segment of cdata // previous sibling - can be a tag, a segment of text, another // comment or a segment of cdata // a list of attribute nodes - unused // a list of child nodes - unused // // For a segment of cdata: // type - CDATA_XMLDOMNODETYPE // name - "cdata" // value - the cdata itself // parent node - the tag containing the cdata // next sibling - can be a tag, a segment of text, a comment // or another segment of cdata // previous sibling - can be a tag, a segment of text, a comment // or another segment of cdata // a list of attribute nodes - unused // a list of child nodes - unused #ifdef RUDIMENTS_NAMESPACE namespace rudiments { #endif // node types enum xmldomnodetype { NULL_XMLDOMNODETYPE=0, ROOT_XMLDOMNODETYPE, TAG_XMLDOMNODETYPE, ATTRIBUTE_XMLDOMNODETYPE, TEXT_XMLDOMNODETYPE, COMMENT_XMLDOMNODETYPE, CDATA_XMLDOMNODETYPE }; class xmldom; class xmldomnodeprivate; class xmldomnode { public: xmldomnode(xmldom *dom, xmldomnode *nullnode); // Creates a new node and intializes its // member variables to NULL. // // Your application should pass in a special // "nullnode" which may be created by the // static method createNullNode() below. // // This will keep command chaining like this: // // mynode->getChild("node1")-> // getChild("node2")->getName("node3"); // // from causing the program to crash trying to // dereference a NULL pointer if, for example, // "node2" doesn't exist. xmldomnode(xmldom *dom, xmldomnode *nullnode, xmldomnodetype type, const char *name, const char *value); // Creates a new node (as above) and intializes // its member variables to the values passed in. ~xmldomnode(); // Deletes the node, all attribute nodes and // optionally all child nodes, recursively. static xmldomnode *createNullNode(xmldom *dom); // Creates a special "null node" whose // parent, next sibling and previous // siblings point back to itself. // // This special node should be passed // in when creating new xmldomnodes. // // This method allocates xmldomnode // internally and passes a pointer // back. The calling program must // ultimately deallocate the node. // These methods control the behavior when the node is deleted. void cascadeOnDelete(); // Instructs the destructor to recursively // delete all child nodes. (the default) void dontCascadeOnDelete(); // Instructs the destructor not to recursively // delete all child nodes. // These methods provide read-access to the data // contained in the node. xmldomnodetype getType() const; // Returns the node type. const char *getName() const; // Returns the node name. const char *getValue() const; // Returns the node value. xmldomnode *getParent() const; // Returns a pointer to the parent node or the // nullnode if none exists. xmldomnode *getPreviousSibling() const; // Returns a pointer to the previous sibling // node or the nullnode if none exists. xmldomnode *getPreviousTagSibling() const; // Returns a pointer to the previous sibling // node whose type is TAG_XMLDOMNODE. If no // match is found, nullnode is returned. xmldomnode *getPreviousTagSibling(const char *name) const; // Returns the previous sibling node named // "name" whose type is TAG_XMLDOMNODE or the // nullnode if not found. xmldomnode *getPreviousTagSibling(const char *name, const char *attributename, const char *attributevalue) const; // Returns the previous sibling node named // "name" with an attribute named // "attributename" with value "attributevalue" // whose type is TAG_XMLDOMNODE. If "name" is // null, then the name of the child node is not // checked, and the first child node with any // name (with matching attribute name/value) // will be returned. If no match is found, // nullnode is returned. xmldomnode *getNextSibling() const; // Returns a pointer to the next sibling node // or the nullnode if none exists. xmldomnode *getNextTagSibling() const; // Returns a pointer to the next sibling node // whose type is TAG_XMLDOMNODE. If no match // is found, nullnode is returned. xmldomnode *getNextTagSibling(const char *name) const; // Returns the next sibling node named "name" // whose type is TAG_XMLDOMNODE or the nullnode // if not found. xmldomnode *getNextTagSibling(const char *name, const char *attributename, const char *attributevalue) const; // Returns the next sibling node named "name" // with an attribute named "attributename" with // value "attributevalue" whose type is // TAG_XMLDOMNODE. If "name" is null, // then the name of the child node is not // checked, and the first child node with any // name (with matching attribute name/value) // will be returned. If no match is found, // nullnode is returned. int getChildCount() const; // Returns the number of immediate child nodes. xmldomnode *getChild(const char *name) const; // Returns the child node named "name" // or the nullnode if not found. xmldomnode *getChild(int position) const; // Returns the child node at index "position" // or the nullnode if not found. xmldomnode *getChild(const char *name, const char *attributename, const char *attributevalue) const; // Returns the first child node named "name" // with an attribute named "attributename" with // value "attributevalue". If "name" is null, // then the name of the child node is not // checked, and the first child node with any // name (with matching attribute name/value) // will be returned. If no match is found, // nullnode is returned. xmldomnode *getFirstTagChild() const; // Returns the first child node whose type is // TAG_XMLDOMNODE. If no match is found, // nullnode is returned. xmldomnode *getFirstTagChild(const char *name) const; // Returns the first child node named "name" // whose type is TAG_XMLDOMNODE. If no match // is found, nullnode is returned. xmldomnode *getFirstTagChild(const char *name, const char *attributename, const char *attributevalue) const; // Returns the first child node named "name" // with an attribute named "attributename" with // value "attributevalue" whose type is // TAG_XMLDOMNODE. If "name" is null, // then the name of the child node is not // checked, and the first child node with any // name (with matching attribute name/value) // will be returned. If no match is found, // nullnode is returned. int getAttributeCount() const; // Returns the number of attributes. xmldomnode *getAttribute(const char *name) const; // Returns the attribute named "name" // or the nullnode if not found. xmldomnode *getAttribute(int position) const; // Returns the attribute node at index // "position" or the nullnode if not found. const char *getAttributeValue(const char *name) const; // Returns the value of the attribute named // "name" or the nullnode if not found. const char *getAttributeValue(int position) const; // Returns the value of the attribute node at // index "position" or the nullnode if not // found. constnamevaluepairs *getAttributes() const; // Returns the attribute names and values in // a constnamevaluepairs dictionary. The // instance of constnamevaluepairs is allocated // internally and must be deleted by the // calling program. Returns NULL if the node // is a nullNode and an empty dictionary if the // node has no attributes. xmldomnode *getNullNode() const; // Returns the nullnode used by this node. bool isNullNode() const; // Returns true if this node is the special // nullnode and false otherwise. // These methods provide write-access to the data contained in // the node. These methods can also be used to move nodes // around in the tree, and insert or delete them. void setType(xmldomnodetype type); // Sets the node type to "type". void setName(const char *name); // Sets the node name to "name". void setValue(const char *value); // Sets the node value to "value". void setParent(xmldomnode *parent); // Sets the parent of the node to "parent". void setPreviousSibling(xmldomnode *previous); // Sets the previous sibling of the node to "previous". void setNextSibling(xmldomnode *next); // Sets the next sibling of the node to "next". bool insertChild(xmldomnode *child, int position); // Inserts "child" into the list of child nodes at // "position". The position of the next sibling // (and all successive siblings) is incremented. bool appendChild(xmldomnode *child); // Appends "child" to the list of child nodes. bool deleteChild(int position); // Deletes the child node at "position". The position // of the next sibling (and all successive siblings) // is decremented. bool deleteChild(xmldomnode *child); // Searches the list of child nodes for "child" and // deletes it. The position of the next sibling (and // all successive siblings) is decremented. bool insertText(const char *value, int position); // Inserts a child node of type TEXT_XMLDOMNODE with // value "value" into the list of child nodes at // "position". The position of the next sibling // (and all successive siblings) is incremented. bool appendText(const char *value); // Appends a child node of type TEXT_XMLDOMNODE with // value "value" to the list of child nodes. bool insertAttribute(xmldomnode *attribute, int position); // Inserts "attribute" into the list of attributes at // "position". The position of the next attribute // (and all successive attributes) is incremented. bool appendAttribute(xmldomnode *attribute); // Appends "attribute" to the list of attributes. bool insertAttribute(const char *name, const char *value, int position); // Creates an attribute node with "name" and "value" // and inserts it into the list of attributes at // "position". The position of the next attribute // (and all successive attributes) is incremented. bool appendAttribute(const char *name, const char *value); // Creates an attribute node with "name" and "value" // and appends it to the list of attributes. bool deleteAttribute(int position); // Deletes the attribute at "position". The position // of the next attribute (and all successive attributes) // is decremented. bool deleteAttribute(const char *name); // Searches the list of attribute nodes for an attribute // named "name" and deletes it. The position of the // next attribute (and all successive attributes) is // decremented. bool deleteAttribute(xmldomnode *attribute); // Searches the list of attribute nodes for "attribute" // and deletes it. The position of the next attribute // (and all successive attributes) is decremented. stringbuffer *xml() const; // Allocates a stringbuffer, writes a textual // representation of the tree starting at this // node to it and returns the stringbuffer; // The calling program must deallocate the // stringbuffer. stringbuffer *getPath() const; // If the xmldomnode is an element, returns the // "path" of the xmldomnode. The path will have // the following form: // // /element[index]/element[index]/... // // The return value is allocated inside the // method and must be deallocated by the calling // program. xmldomnode *getChildByPath(const char *path) const; // Returns the child element with "path" of the // form: // // /element[index]/element[index]/... // // Returns the null node if the specified // element was not found. xmldomnode *getAttributeByPath(const char *path, int position) const; // Returns the attribute node at index // "position" of the child element with "path" // of the form: // // /element[index]/element[index]/... // // Returns the null node if the specified // element was not found. xmldomnode *getAttributeByPath(const char *path, const char *name) const; // Returns the attribute node named "name" // of the child element with "path" of the form: // // /element[index]/element[index]/... // // Returns the null node if the specified // element was not found. const char *getAttributeValueByPath(const char *path, int position) const; // Returns the value of the attribute at index // "position" of the child element with "path" // of the form: // // /element[index]/element[index]/... // // Returns the null node if the specified // element was not found. const char *getAttributeValueByPath(const char *path, const char *name) const; // Returns the value of the attribute named // "name" of the child element with "path" of // the form: // // /element[index]/element[index]/... // // Returns the null node if the specified // element was not found. #include <rudiments/private/xmldomnode.h> }; #ifdef RUDIMENTS_NAMESPACE } #endif #endif