I'm using CodeSynthesis XSD tool to generate XML file according to a given XSD file. I know that it's possible to build an XML tree and serialize it to a stream. But my question is:
Is it possible to generate the XML elements one by one?
Suppose I want to generate a <root>
element which contains <element1>
and <element2>
. Now I can only build the <root>
tree and serialize it in one piece. What I want is:
First generate <root>
, then <element1>...</element1>
and <element2>...</element2>
, finally </root>
.
Because the parser support callbacks, it's easy to take control of each node immediately after the node is available. Is it possible for tree mapping also?
I dig the documentation but didn't found a proper answer. I'll appreciate any possible help or clues. Thanks in advance :)
--- Edit ---
To make it clear - First, the source XML data are generated by my program (not from existing XML file); Second, I want to serialize the XML object immediately after it is produced, instead of serializing a whole tree.
I know XSD/Tree targets on in-memory tree-like processing, but I wonder if it's possible to write like xxx_open
and xxx_close
etc.
Thanks again.
Yes, it is possible to generate the elements one by one with CodeSynthesis XSD. For instance, this streaming example generates this XML file:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<op:object xmlns:op="http://www.codesynthesis.com/op" id="123" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.codesynthesis.com/op position.xsd">
<header>
<name>Lion's Head</name>
<type>rock</type>
</header>
<position lat="-33.8569" lon="18.5083"/>
<position lat="-33.8568" lon="18.5083"/>
<position lat="-33.8568" lon="18.5082"/>
<position lat="-33.857" lon="18.5083"/>
<position lat="-33.8569" lon="18.5084"/>
<position lat="-33.857" lon="18.5084"/>
<position lat="-33.857" lon="18.5082"/>
<position lat="-33.8569" lon="18.5082"/>
</op:object>
In the file driver.cxx each position element is generated by calling
s.next ("position", pos);
To have more control over what namespace prefixes will be used in the output, you could use this function instead from the file serializer.hxx
// Serialize next object model fragment into an element with the specified
// namespace and qualified name as well as namespace declarations.
//
template <typename T>
void
next (const std::string& ns,
const std::string& name,
const namespace_infomap&,
const T& x);
In the file driver.cxx the position object is being created out of a XML DOM tree
position pos (*doc1->getDocumentElement ());
so it is this constructor that is being used:
position (const ::xercesc::DOMElement& e,
::xml_schema::flags f = 0,
::xml_schema::container* c = 0);
that can be seen in the generated file position.hxx.
But you mention that you are creating your objects out of a non-XML source, so you would instead need to use the constructor that takes the member values as input:
position (const lat_type&,
const lon_type&);