From efc69e19997e52a43691b6211558ad90b7211dac Mon Sep 17 00:00:00 2001
From: Malcolm McLean
+The miniXML parser source file, xmlparser2.c, is a set of functions designed to work with XML files. The functions make it easy for programmers to use these files and to manipulate them. It is not part of Baby X and therefore doesn't take the bbx prefix.
+
+
+These are the functions in the library.
+
+
+
+xmlparser2
+The functions
+
+
+
+ #ifndef xmlparser_h
+ #define xmlparser_h
+
+ #include <stdio.h>
+
+ typedef struct xmlattribute
+ {
+ char *name; /* attribute name */
+ char *value; /* attribute value (without quotes) */
+ struct xmlattribute *next; /* next pointer in linked list */
+ } XMLATTRIBUTE;
+
+ typedef struct xmlnode
+ {
+ char *tag; /* tag to identify data type */
+ XMLATTRIBUTE *attributes; /* attributes */
+ char *data; /* data as ascii */
+ int position; /* position of the node within parent's data string */
+ int lineno; /* line number of node in document */
+ struct xmlnode *next; /* sibling node */
+ struct xmlnode *child; /* first child node */
+ } XMLNODE;
+
+ typedef struct
+ {
+ XMLNODE *root; /* the root node */
+ } XMLDOC;
+
+
+ XMLDOC *loadxmldoc(const char *fname, char *errormessage, int Nerr);
+ XMLDOC *floadxmldoc(FILE *fp, char *errormessage, int Nerr);
+ XMLDOC *xmldocfromstring(const char *str,char *errormessage, int Nerr);
+ void killxmldoc(XMLDOC *doc);
+ void killxmlnode(XMLNODE *node);
+
+ XMLNODE *xml_getroot(XMLDOC *doc);
+ const char *xml_gettag(XMLNODE *node);
+ const char *xml_getdata(XMLNODE *node);
+ const char *xml_getattribute(XMLNODE *node, const char *attr);
+ int xml_Nchildren(XMLNODE *node);
+ int xml_Nchildrenwithtag(XMLNODE *node, const char *tag);
+ XMLNODE *xml_getchild(XMLNODE *node, const char *tag, int index);
+ XMLNODE **xml_getdescendants(XMLNODE *node, const char *tag, int *N);
+ char *xml_getnesteddata(XMLNODE *node);
+
+ int xml_getlineno(XMLNODE *node);
+ XMLATTRIBUTE *xml_unknownattributes(XMLNODE *node, ...);
+
+ #endif
+
+
+Loads an XML file and returns an XMLDOC object. +
++ XMLDOC *loadxmldoc(const char *fname, char *errormessage, int Nerr); + Params: + fname - the name of the file to load. + errormesssage - return buffer for error messages. + Nerr - size of the error message buffer. + + Returns: the constructed XMLDOC object. + ++ +This is the main function to load an XML filr from disk and parse it. The XMl loader is quite good, and will load UTF-16 and convert to UTF-8. Ir's also got fairly strong error reporting + + +
+Loads XML from an open stream and returns an XMLDOC object. +
++
+ XMLDOC *floadxmldoc(FILE *fp, char *errormessage, int Nerr); + + Params: + fp - pointer to a file opened for reading. + errormessage - return buffer for error messages + Nerr - size of the error message buffer + + Returns: the constructed XMLDOC object. + ++loadxmldoc isof course just a wrapper for this function, which is exposed in case you have data coming from an open stream and can't provide a filename. + + +
+Reads XML from a string, and returns an XMLDOC object. +
++
+ XMLDOC *xmldocfromstring(const char *str,char *errormessage, int Nerr); + + Params: + str - a string conatining xml. + errormesssage - retun buffer for error messages. + Nerr - size of the error message bufffer. + + Returns: the constructed XMLDOC object. ++ +
+Pass it a string with XML to use the system in an IO-free manner. +
+ ++
+ void killxmldoc(XMLDOC *doc); + Params: + doc - the XMLDOC object to destroy. + ++ +
+This destroys an XMLDOC. XML documents can get vey large, and so you want to destroy them as soon as possible. +
+ ++Destroys an XMLNODE, its siblings, and its children. +
++
+ void killxmlnode(XMLNODE *node); + Params: + node - the XMLNODE object to destroy. + ++ +
+The function will destroy all of the siblings of the xml node.b So the node must be unlinked before calling +
+ ++Returns the root node of the XMLDOC object. +
++
+ XMLNODE *xml_getroot(XMLDOC *doc); + Params: + doc - the XMLDOC object. + + Returns: root node of the document. + ++ +
+Access function. Never access the root directly, unless actually writng to it for some reason. +
+ ++Gets the tag or element name associated with a node. +
++
+ const char *xml_gettag(XMLNODE *node); + Params: + node - the XMLNODE. + + Returns: the tag or element name associated with the node. + ++ +
+Access function. You get a bit of security with "const"."" +
+ ++gets the data associated with the node. +
++
+ const char *xml_getdata(XMLNODE *node); + Params: + node - the XMLNODE object. + + Returns: the data associed with the node. ++ +
+Some nodes have data, and other will just have whitespece, which nevertheless must be preeseved, If a node was in the closed single args form (<s;mystg />) the the data element should be null. +
++Get an attribute attached to a node. +
++
+ const char *xml_getattribute(XMLNODE *node, const char *attr); + Params: + node - the XMLNODE object. + attr - the name of the attribute to query + Returns: the value of the attribute, or null if it does not exist. ++ +
+The attributesa are stored in a linked list. The function traverse he list and reports the first match. +
++Get the number of direct children of the node. +
++
+ int xml_Nchildren(XMLNODE *node); + Params: + node - the XMLNODE object. + + Returns: number of direct children of the node. ++ +
+Cinvenience functio to count the cgildren. +
++Get the number of direct children of a node associated wih a tag. +
++
+ int xml_Nchildrenwithtag(XMLNODE *node, const char *tag); + Params: + node - the XMLNODE object. + tag - thetag or element name to query. + Returns: the number of direct children with thaat tag type. ++ +
+Convenience function to get the nodes of the tag type we are inrerested in. +
++Get the node's first child. +
++
+ XMLNODE *xml_getchild(XMLNODE *node, const char *tag, int index); + Params: + node - the XMLNODE object. + tag - the tag to query. + index - seniority of the child with that tag + Returns: the child with that tag, as referenced by index ++ +
+Sccess fucntion to first child. +
++Get all the descendants of a node associated with a tag. +
++
+ XMLNODE **xml_getdescendants(XMLNODE *node, const char *tag, int *N); + Params: + node - the XMLNODE object. + tag - the tag to query + N - return pointer for the number of descendants found. + Returns: an allocated list of all the descendants of that node. ++ +
+This is often what you want to do. +
++Get the data held by a node and its descendants. +
++
+ char *xml_getnesteddata(XMLNODE *node); + Params: + node - the XMLNODE object. + + Returns: allocated pointer to the data held by the nodecand its children.. ++ +
+This is needed for XML which is raeup instead of tagged data. The node needs to know the positons of any childre within its data string. +
+ ++Get the number of the line in the XML document where the node appeared. +
++
+ int xml_getlineno(XMLNODE *node); + Params: + node - the XMLNODE object. + + Returns: the line number the node appeared in the XML document. ++ +
+This is an absolutely crucial little function for reporting errors. XML fles often get very large, and withot some reference to the place a corrupted node appears in the data, repair is hopeless. +
+ ++Return any attributes which do not match a list of known attributes. +
++
+ XMLATTRIBUTE *xml_unknownattributes(XMLNODE *node, ...) + Params: + node - the XMLNODE object. + ... - a list of known attributes associated with the node. + Returns: an allocated linked list of attributes not in thev list + of known attributes. ++ +
+This is another function mainly for debugging. Nodes might have unkown attributes associated with them. Which will often indicate a bug somewhere upstream. +
++You use it ike this +
+ void *sentinel = 0; + XMLARRIBUTE *attr; + + attr = xml_unknownattriby=uyes(node, "faith", "hope" charity, sentinel); + if (!attr) + { + /* all ok */ + } + /* now ww have deep copy of tha unknown attriubutes. + ++
+
+XML is a recognised format for files. +
+ + +