CodeSynthesis XSD tree serialization on the fly

1k views Asked by At

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.

1

There are 1 answers

3
Erik Sjölund On BEST ANSWER

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&);