simple XML for C++ application data-file I/O
Paul Miller
stele at fxtech.com
Mon Dec 6 14:47:41 GMT 1999
This is what I had in mind. Consider this (contrived) XML data-file,
that consists of a Title, Author, and one or more Paragraph elements:
<Document name="mydoc.doc">
<Title>Sample XML Document</Title>
<Author email="paul at fxtech.com">Paul Miller</Author>
<Paragraph>
This is the first paragraph.
</Paragraph>
<Paragraph>
This is the second paragraph.
</Paragraph>
</Document>
Now, expat and SAX only give you the elements, so you have to keep track
of where you are in the document in the element handler yourself. What I
have in mind is a nestable set of registered element handlers,
implemented as callbacks. The callbacks are static function pointers,
since I want a non-intrusive design.
With this example, I assume two primary classes (Document and
Paragraph). Although Title and Author are represented as elements here,
they are really attributes of the Document object. Now consider this
code to parse it:
void ParseDocument(XML::InputStream &in)
{
XML::ElementHandler handlers[] = {
XML::ElementHandler("Document", sParseDocument),
XML::ElementHandler::END
};
in.Parse(handlers, NULL); // NULL is optional user-data
}
static void
sParseDocument(XML::InputStream &in, XML::Element &elem, void *userData)
{
// query the name attribute
std::string docName;
elem.GetAttribute("name", docName);
// create a new document with this name
Document *doc = new Document(docName);
XML::ElementHandler handlers[] = {
XML::ElementHandler("Title", sParseTitle),
XML::ElementHandler("Author", sParseAuthor),
XML::ElementHandler("Paragraph", sParseParagraph),
XML::ElementHandler::END
};
// parse the document elements
in.Parse(handlers, doc);
}
static void
Document::sParseTitle(XML::InputStream &in, XML::Element &elem, void
*userData)
{
Document *doc = (Document *)userData;
doc->SetTitle(elem.GetData());
}
static void
Document::sParseAuthor(XML::InputStream &in, XML::Element &elem, void
*userData)
{
Document *doc = (Document *)userData;
doc->SetAuthor(elem.GetData(), elem.GetAttribute());
}
static void
Document::sParseParagraph(XML::InputStream &in, XML::Element &elem, void
*userData)
{
Document *doc = (Document *)userData;
Paragraph *para = new Paragraph;
para->Parse(in, elem);
doc->AddParagraph(para);
}
void Paragraph::Parse(XML::InputStream &in, XML::Element &elem)
{
SetText(elem.GetData());
}
The major idea here is you register everything up-front, and
element-specific callbacks get called to deal with specific elements.
You can start up parsing inside an element, so you can nest parsing at
the object level.
Comments?
--
Paul Miller - stele at fxtech.com
xml-dev: A list for W3C XML Developers. To post, mailto:xml-dev at ic.ac.uk
Archived as: http://www.lists.ic.ac.uk/hypermail/xml-dev/ and on CD-ROM/ISBN 981-02-3594-1
To unsubscribe, mailto:majordomo at ic.ac.uk the following message;
unsubscribe xml-dev
To subscribe to the digests, mailto:majordomo at ic.ac.uk the following message;
subscribe xml-dev-digest
List coordinator, Henry Rzepa (mailto:rzepa at ic.ac.uk)
More information about the Xml-dev
mailing list