// file : xsd/cxx/xml/dom/serialization.txx // author : Boris Kolpackov // copyright : Copyright (c) 2005 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include namespace xsd { namespace cxx { namespace xml { namespace dom { namespace bits { template C const* load_store (); template C const* xmlns_prefix (); template C const* xmlns_namespace (); template C const* xsi_prefix (); template C const* xsi_namespace (); template C const* schema_location (); template C const* no_namespace_schema_location (); // char // template <> inline char const* load_store () { return "LS"; } template <> inline char const* xmlns_prefix () { return "xmlns"; } template <> inline char const* xmlns_namespace () { return "http://www.w3.org/2000/xmlns/"; } template <> inline char const* xsi_prefix () { return "xsi"; } template <> inline char const* xsi_namespace () { return "http://www.w3.org/2001/XMLSchema-instance"; } template <> inline char const* schema_location () { return "schemaLocation"; } template <> inline char const* no_namespace_schema_location () { return "noNamespaceSchemaLocation"; } // wchar_t // template <> inline wchar_t const* load_store () { return L"LS"; } template <> inline wchar_t const* xmlns_prefix () { return L"xmlns"; } template <> inline wchar_t const* xmlns_namespace () { return L"http://www.w3.org/2000/xmlns/"; } template <> inline wchar_t const* xsi_prefix () { return L"xsi"; } template <> inline wchar_t const* xsi_namespace () { return L"http://www.w3.org/2001/XMLSchema-instance"; } template <> inline wchar_t const* schema_location () { return L"schemaLocation"; } template <> inline wchar_t const* no_namespace_schema_location () { return L"noNamespaceSchemaLocation"; } } } } } } namespace xsd { namespace cxx { namespace xml { namespace dom { template xsd::cxx::xml::dom::auto_ptr dom (std::basic_string const& el, std::basic_string const& ns, namespace_infomap const& map) { using namespace xercesc; typedef std::basic_string string; typedef namespace_infomap infomap; typedef typename infomap::const_iterator infomap_iterator; C colon (':'), space (' '); string prefix; if (!ns.empty ()) { infomap_iterator i (map.begin ()), e (map.end ()); for ( ;i != e; ++i) { if (i->second.name == ns) { prefix = i->first; break; } } if (i == e) throw mapping (ns); } DOMImplementation* impl ( DOMImplementationRegistry::getDOMImplementation ( xml::string (bits::load_store ()).c_str ())); auto_ptr doc ( impl->createDocument ( (ns.empty () ? 0 : xml::string (ns).c_str ()), xml::string ((prefix.empty () ? el : prefix + colon + el)).c_str (), 0)); DOMElement* root (doc->getDocumentElement ()); // Check if we need to provide xsi mapping. // bool xsi (false); string xsi_prefix (bits::xsi_prefix ()); string xmlns_prefix (bits::xmlns_prefix ()); for (infomap_iterator i (map.begin ()), e (map.end ()); i != e; ++i) { if (!i->second.schema.empty ()) { xsi = true; break; } } // Check if we were told to provide xsi mapping. // if (xsi) { for (infomap_iterator i (map.begin ()), e (map.end ()); i != e; ++i) { if (i->second.name == bits::xsi_namespace ()) { xsi_prefix = i->first; xsi = false; break; } } if (xsi) { // If we were not told to provide xsi mapping, make sure our // prefix does not conflict with user-defined prefixes. // infomap_iterator i (map.find (xsi_prefix)); if (i != map.end ()) throw xsi_already_in_use (); } } // Create xmlns:xsi attribute. // if (xsi) { root->setAttributeNS ( xml::string (bits::xmlns_namespace ()).c_str (), xml::string (xmlns_prefix + colon + xsi_prefix).c_str (), xml::string (bits::xsi_namespace ()).c_str ()); } // Create user-defined mappings. // for (infomap_iterator i (map.begin ()), e (map.end ()); i != e; ++i) { if (i->first.empty ()) { // Empty prefix. // root->setAttributeNS ( xml::string (bits::xmlns_namespace ()).c_str (), xml::string (xmlns_prefix).c_str (), xml::string (i->second.name).c_str ()); } else { root->setAttributeNS ( xml::string (bits::xmlns_namespace ()).c_str (), xml::string (xmlns_prefix + colon + i->first).c_str (), xml::string (i->second.name).c_str ()); } } // Create xsi:schemaLocation and xsi:noNamespaceSchemaLocation // attributes. // string schema_location; string no_namespace_schema_location; for (infomap_iterator i (map.begin ()), e (map.end ()); i != e; ++i) { if (!i->second.schema.empty ()) { if (i->second.name.empty ()) { no_namespace_schema_location += no_namespace_schema_location.empty () ? i->second.schema : space + i->second.schema; } else { schema_location += i->second.name + space + i->second.schema; } } } if (!schema_location.empty ()) { root->setAttributeNS ( xml::string (bits::xsi_namespace ()).c_str (), xml::string (xsi_prefix + colon + bits::schema_location ()).c_str (), xml::string (schema_location).c_str ()); } if (!no_namespace_schema_location.empty ()) { root->setAttributeNS ( xml::string (bits::xsi_namespace ()).c_str (), xml::string (xsi_prefix + colon + bits::no_namespace_schema_location ()).c_str (), xml::string (no_namespace_schema_location).c_str ()); } return doc; } template bool serialize (xercesc::XMLFormatTarget& target, xercesc::DOMDocument const& doc, std::basic_string const& encoding, xercesc::DOMErrorHandler* h) { using namespace xercesc; DOMImplementation* impl ( DOMImplementationRegistry::getDOMImplementation ( xml::string (bits::load_store ()).c_str ())); // Get an instance of DOMWriter. // error_handler eh (h); xml::dom::auto_ptr writer (impl->createDOMWriter ()); writer->setErrorHandler (&eh); writer->setEncoding(xml::string (encoding).c_str ()); // Set some nice features if the serializer supports them. // if (writer->canSetFeature (XMLUni::fgDOMWRTDiscardDefaultContent, true)) writer->setFeature (XMLUni::fgDOMWRTDiscardDefaultContent, true); if (writer->canSetFeature (XMLUni::fgDOMWRTFormatPrettyPrint, true)) writer->setFeature (XMLUni::fgDOMWRTFormatPrettyPrint, true); writer->writeNode (&target, doc); if (eh.failed ()) return false; return true; } } } } }