[xsd-users] Saving Partial XSD trees

Paul McGrath paul.s.mcgrath at gmail.com
Wed Oct 26 15:58:10 EDT 2022


I have been working through the cxx/tree/messaging example and altering it
to my purpose.

I have been able to input the file and output the file, however the output
is missing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="matml31_lib.xsd" in the element when you
compare it to the input file.

Below is my adoption of the code as a Set and Get template functions.

#pragma once

#include <memory>   // std::auto_ptr
#include <string>
#include <fstream>
#include <typeinfo>
#include <iostream>

#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/PlatformUtils.hpp>

#include <xsd/cxx/xml/string.hxx>

#include "dom-parse.hxx"
#include "dom-serialize.hxx"

#include "matml31_lib.hxx"

using namespace bellshire;

template <class MatML_Class>
bool MatML_Lib::Get(const std::string filename, MatML_Class*& element)
{
    //// We need to initialize the Xerces-C++ runtime because we
    //// are doing the XML-to-DOM parsing ourselves.
    ////
    //::xercesc::XMLPlatformUtils::Initialize();

    bool r(true);

    try
    {

        std::ifstream ifs;
        ifs.exceptions(std::ifstream::badbit | std::ifstream::failbit);
        ifs.open(filename);

        std::auto_ptr<xml_schema::element_type> req;

        // Parse the XML request to a DOM document using the parse()
        // function from dom-parse.hxx.
        //
        {
            xml_schema::dom::auto_ptr<::xercesc::DOMDocument>
doc(parse(ifs, filename, true));
            ::xercesc::DOMElement& root(*doc->getDocumentElement());

            req = xml_schema::element_map::parse(root);
        }

        // We can test which request we've got either using RTTI.
        //
        element = dynamic_cast<MatML_Class*> (req.get()->_clone());
        if (element)
        {
            r = true;
        }

    }
    catch (const xml_schema::no_element_info& e)
    {
        // This exception indicates that we tried to parse or serialize
        // an unknown element.
        //
        std::cerr << "unknown request: " << e.element_namespace() << "#" <<
            e.element_name() << std::endl;
        r = false;
    }
    catch (const xml_schema::exception& e)
    {
        std::cerr << e << std::endl;
        r = false;
    }
    catch (const std::ios_base::failure&)
    {
        std::cerr << filename << ": unable to open or read failure" <<
std::endl;
        r = false;
    }

    //::xercesc::XMLPlatformUtils::Terminate();
    return r;
}

template <class MatML_Class>
bool MatML_Lib::Set(const std::string filename, MatML_Class*& element)
{
    // We need to initialize the Xerces-C++ runtime because we
    // are doing the XML-to-DOM parsing ourselves.
    //
    //::xercesc::XMLPlatformUtils::Initialize();

    bool r(true);

    try
    {
        std::ofstream ofs;
        ofs.exceptions(std::ofstream::badbit | std::ofstream::failbit);
        ofs.open(filename);

        std::auto_ptr<xml_schema::element_type> res(element->_clone());

        // Serialize the response to a DOM document.
       //
        namespace xml = xsd::cxx::xml;

        const XMLCh ls_id[] = { xercesc::chLatin_L, xercesc::chLatin_S,
xercesc::chNull };

        ::xercesc::DOMImplementation* impl(

::xercesc::DOMImplementationRegistry::getDOMImplementation(ls_id));

        const std::string& name(res->_name());
        const std::string& ns(res->_namespace());

        xml_schema::dom::auto_ptr<::xercesc::DOMDocument> doc(
            impl->createDocument(
                xml::string(ns).c_str(),
                xml::string("" + name).c_str(),
                0));

        xml_schema::element_map::serialize(*doc->getDocumentElement(),
*res);

        // Serialize the DOM document to XML using the serialize() function
        // from dom-serialize.hxx.
        //
        //std::cout << "response:" << std::endl
        //    << std::endl;

        serialize(/*std::cout*/ofs, *doc);

    }
    catch (const xml_schema::no_element_info& e)
    {
        // This exception indicates that we tried to parse or serialize
        // an unknown element.
        //
        std::cerr << "unknown request: " << e.element_namespace() << "#" <<
            e.element_name() << std::endl;
        r = false;
    }
    catch (const xml_schema::exception& e)
    {
        std::cerr << e << std::endl;
        r = false;
    }
    catch (const std::ios_base::failure&)
    {
        std::cerr << filename << ": unable to open or read failure" <<
std::endl;
        r = false;
    }

    //::xercesc::XMLPlatformUtils::Terminate();
    return r;
}

On Sun, Sep 11, 2022 at 7:39 AM Boris Kolpackov <boris at codesynthesis.com>
wrote:

> Paul McGrath <paul.s.mcgrath at gmail.com> writes:
>
> > I'm looking to save sequences without requiring having to save the whole
> > tree. The rationale behind this is to create a library of elements that
> can
> > be then cloned into a tree.
>
> Each XML Schema type is mapped to a C++ class that comes with a
> parsing constructor (from DOMElement) and a serialization operator<<
> (to DOMElement). So with some effort (i.e., create suitable DOMElement,
> etc) you should be able to serialize a sequence of instances of such
> classes.
>
> The closest example to what you are trying to achieve is probably
> cxx/tree/messaging/ (it also comes with DOM parsing/serialization
> helpers which you will most likely find useful). There is also
> cxx/tree/streaming/ that you may find relevant.
>


More information about the xsd-users mailing list