diff options
Diffstat (limited to 'CIAO/tools/Config_Handlers/XSCRT/XML.hpp')
-rw-r--r-- | CIAO/tools/Config_Handlers/XSCRT/XML.hpp | 490 |
1 files changed, 490 insertions, 0 deletions
diff --git a/CIAO/tools/Config_Handlers/XSCRT/XML.hpp b/CIAO/tools/Config_Handlers/XSCRT/XML.hpp new file mode 100644 index 00000000000..1f11533e2bb --- /dev/null +++ b/CIAO/tools/Config_Handlers/XSCRT/XML.hpp @@ -0,0 +1,490 @@ +// file : XSCRT/XML.hpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + + +#ifndef XSCRT_XML_HPP +#define XSCRT_XML_HPP + +#include <string> + +#include <xercesc/dom/DOM.hpp> +#include <xercesc/util/XMLString.hpp> + +namespace XSCRT +{ + namespace XML + { + //@@ VC6 + // + template <typename C> + std::basic_string<C> + transcode (XMLCh const* s, C*); + + template <typename C> + XMLCh* + transcode (std::basic_string<C> const& s); + + // + // + // + class string + { + public : + template <typename C> + string (std::basic_string<C> const& s) + : s_ (XSCRT::XML::transcode<C> (s)) + { + } + + template <typename C> + string (C const* s) + : s_ (XSCRT::XML::transcode<C> (s)) + { + } + + ~string () + { + delete[] s_; + } + + XMLCh const* + c_str () const + { + return s_; + } + + private : + XMLCh* s_; + }; + + + template <> + inline + std::basic_string<char> + transcode<char> (XMLCh const* s, char*) + { + if (s == 0) return std::basic_string<char> (); + + char* buf = xercesc::XMLString::transcode (s); + + std::basic_string<char> r (buf); + + xercesc::XMLString::release (&buf); + + return r; + } + + template <> + inline + std::basic_string<wchar_t> + transcode<wchar_t> (XMLCh const* s, wchar_t*) + { + if (s == 0) return std::basic_string<wchar_t> (); + + // std::wcerr << s << std::endl; + + std::basic_string<wchar_t> r (xercesc::XMLString::stringLen (s), L'0'); + + for (std::size_t i (0); *s != XMLCh (0); ++s, ++i) + { + r[i] = *s; + } + + return r; + } + + template <> + inline + XMLCh* + transcode (std::basic_string<char> const& s) + { + return xercesc::XMLString::transcode (s.c_str ()); + } + + template <> + inline + XMLCh* + transcode (std::basic_string<wchar_t> const& s) + { + //@@ VC6 + std::size_t l = s.length (); + + //@@ VC6 + XMLCh* r = new XMLCh[l + 1]; + XMLCh* ir = r; + + for (std::size_t i (0); i < l; ++ir, ++i) + { + *ir = static_cast<XMLCh>(s[i]); + //std::wcerr << s[i] << "->" << *ir << std::endl; + } + + *ir = XMLCh (0); + + // std::wcerr << r << std::endl; + + return r; + } + + + template <typename C> + class Element; + + template <typename C> + std::basic_string<C> + ns_prefix (std::basic_string<C> const& ns, Element<C> const& e); + + // Casting helpers, made necessary by the Xerces project's braindead + // avoidance of RTTI. + template <typename DERIVED> struct dom_traits; + + // Specializations for different node types + template <> + struct dom_traits<xercesc::DOMElement *> + { + enum { node_type = xercesc::DOMNode::ELEMENT_NODE }; + }; + + template <> + struct dom_traits<xercesc::DOMAttr *> + { + enum { node_type = xercesc::DOMNode::ATTRIBUTE_NODE }; + }; + + template <typename DERIVED_PTR> + DERIVED_PTR dom_cast (xercesc::DOMNode *node) + { + DERIVED_PTR elem = 0; + if ((node != 0) && + (node->getNodeType () == dom_traits<DERIVED_PTR>::node_type)) + { + elem = reinterpret_cast <DERIVED_PTR> (node); + } + return elem; + } + + template <typename C> + class Element + { + typedef std::basic_string<C> string_; + + public: + Element (xercesc::DOMElement const* e) + : e_ (0), + ce_ (e), + name_ (transcode<C> (e->getLocalName (), 0)), + namespace__ (transcode<C> (e->getNamespaceURI (), 0)) + { + } + + Element (xercesc::DOMElement* e) + : e_ (e), + ce_ (e), + name_ (transcode<C> (e->getLocalName (), 0)), + namespace__ (transcode<C> (e->getNamespaceURI (), 0)) + { + } + + Element (string_ const& name, Element& parent) + : e_ (0), + ce_ (0), + name_ (name) + { + xercesc::DOMDocument* doc ( + parent.dom_element ()->getOwnerDocument ()); + + e_ = doc->createElement (string (name).c_str ()); + + parent.dom_element ()->appendChild (e_); + + ce_ = e_; + } + + Element (string_ const& name, string_ const& ns, Element& parent) + : e_ (0), + ce_ (0), + name_ (name), + namespace__ (ns) + { + string_ prefix (ns_prefix (ns, parent)); + + xercesc::DOMDocument* doc ( + parent.dom_element ()->getOwnerDocument ()); + + e_ = doc->createElementNS ( + string (ns).c_str (), + string (prefix.empty () + ? name + : prefix + string_ (1, ':') + name).c_str ()); + + parent.dom_element ()->appendChild (e_); + + ce_ = e_; + } + + public: + string_ + name () const + { + return name_; + } + + string_ + namespace_ () const + { + return namespace__; + } + + public: + Element<C> + parent () const + { + return dom_cast <xercesc::DOMElement const*>(ce_->getParentNode ()); + } + + public: + string_ + value () const + { + return XML::transcode<C> (dom_element ()->getTextContent (), 0); + } + + void + value (string_ const& v) + { + xercesc::DOMText* text ( + dom_element ()->getOwnerDocument ()->createTextNode( + string (v).c_str ())); + + dom_element ()->appendChild (text); + } + + public: + string_ + operator[] (string_ const& s) const + { + //@@ VC6 + XMLCh const* value = ce_->getAttribute (string (s).c_str ()); + + return transcode<C> (value, 0); + } + + public: + xercesc::DOMElement const* + dom_element () const + { + return ce_; + } + + xercesc::DOMElement* + dom_element () + { + return e_; + } + + private: + xercesc::DOMElement* e_; + xercesc::DOMElement const* ce_; + + string_ name_; + string_ namespace__; + }; + + + template <typename C> + class Attribute + { + typedef std::basic_string<C> string_; + + public: + Attribute (xercesc::DOMAttr const* a) + : a_ (0), + ca_ (a), + name_ (transcode<C> (a->getLocalName (), 0)), + value_ (transcode<C> (a->getValue (), 0)) + { + } + + Attribute (xercesc::DOMAttr* a) + : a_ (a), + ca_ (a), + name_ (transcode<C> (a->getLocalName (), 0)), + value_ (transcode<C> (a->getValue (), 0)) + { + } + + Attribute (string_ const& name, + string_ const& v, + Element<C>& parent) + : a_ (0), + ca_ (0), + name_ (name), + value_ () + { + xercesc::DOMDocument* doc ( + parent.dom_element ()->getOwnerDocument ()); + + a_ = doc->createAttribute (string (name).c_str ()); + + value (v); + + parent.dom_element ()->setAttributeNode (a_); + + ca_ = a_; + } + + Attribute (string_ const& name, + string_ const& ns, + string_ const& v, + Element<C>& parent) + : a_ (0), + ca_ (0), + name_ (name), + value_ () + { + string_ prefix (ns_prefix (ns, parent)); + + xercesc::DOMDocument* doc ( + parent.dom_element ()->getOwnerDocument ()); + + a_ = doc->createAttributeNS ( + string (ns).c_str (), + string (prefix.empty () + ? name + : prefix + string_ (1, ':') + name).c_str ()); + + value (v); + + parent.dom_element ()->setAttributeNodeNS (a_); + + ca_ = a_; + } + + string_ + name () const + { + return name_; + } + + string_ + value () const + { + return value_; + } + + void + value (string_ const& v) + { + value_ = v; + a_->setValue (string (v).c_str ()); + } + + public: + xercesc::DOMAttr const* + dom_attribute () const + { + return ca_; + } + + xercesc::DOMAttr* + dom_attribute () + { + return a_; + } + + private: + + private: + xercesc::DOMAttr* a_; + xercesc::DOMAttr const* ca_; + + string_ name_; + string_ value_; + }; + + template <typename C> + std::basic_string<C> + prefix (std::basic_string<C> const& n) + { + std::size_t i (0); + while (i < n.length () && n[i] != ':') ++i; + + //std::wcerr << "prefix " << n << " " + // << std::wstring (n, i == n.length () ? i : 0, i) << std::endl; + + return std::basic_string<C> (n, i == n.length () ? i : 0, i); + } + + template <typename C> + std::basic_string<C> + uq_name (std::basic_string<C> const& n) + { + std::size_t i (0); + while (i < n.length () && n[i] != ':') ++i; + + return std::basic_string<C> (n.c_str () + (i == n.length () ? 0 : i + 1)); + } + + template <typename C> + std::basic_string<C> + ns_name (Element<C> const& e, std::basic_string<C> const& n) + { + std::basic_string<C> wp (prefix (n)); + + //@@ VC6 + XMLCh const* xns = e.dom_element ()->lookupNamespaceURI ( + wp.empty () ? 0 : string (wp).c_str ()); + + + std::basic_string<C> ns ( + xns ? transcode<C> (xns, 0) : std::basic_string<C> ()); + + return ns; + + } + + template <typename C> + std::basic_string<C> + fq_name (Element<C> const& e, std::basic_string<C> const& n) + { + std::basic_string<C> ns (ns_name (e, n)); + std::basic_string<C> un (uq_name (n)); + + return ns.empty () ? un : (ns + C ('#') + un); + } + + class no_prefix {}; + + template <typename C> + std::basic_string<C> + ns_prefix (std::basic_string<C> const& ns, Element<C> const& e) + { + string xns (ns); + + XMLCh const* p ( + e.dom_element ()->lookupNamespacePrefix (xns.c_str (), false)); + + if (p == 0) + { + bool r (e.dom_element ()->isDefaultNamespace (xns.c_str ())); + + if (r) + { + return std::basic_string<C> (); + } + else + { + throw no_prefix (); + } + } + + return transcode<C> (p, 0); + } + } +} + +#include "XSCRT/XML.ipp" +#include "XSCRT/XML.tpp" + +#endif // XSCRT_XML_HPP |