Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / XML_Utils / XSCRT / XML.hpp
blob6f2079e28521138194afbc77b6f7ecf7bc8ab549
1 // file : XSCRT/XML.hpp
2 // author : Boris Kolpackov <boris@dre.vanderbilt.edu>
4 #ifndef XSCRT_XML_HPP
5 #define XSCRT_XML_HPP
7 #include <string>
9 #include <xercesc/dom/DOM.hpp>
10 #include <xercesc/util/XMLString.hpp>
12 namespace XSCRT
14 namespace XML
16 //@@ VC6
18 template <typename C>
19 std::basic_string<C>
20 transcode (XMLCh const* s, C*);
22 template <typename C>
23 XMLCh*
24 transcode (std::basic_string<C> const& s);
29 class string
31 public :
32 template <typename C>
33 string (std::basic_string<C> const& s)
34 : s_ (XSCRT::XML::transcode<C> (s))
38 template <typename C>
39 string (C const* s)
40 : s_ (XSCRT::XML::transcode<C> (s))
44 ~string ()
46 delete[] s_;
49 XMLCh const*
50 c_str () const
52 return s_;
55 private :
56 XMLCh* s_;
60 template <>
61 inline
62 std::basic_string<char>
63 transcode<char> (XMLCh const* s, char*)
65 if (s == 0) return std::basic_string<char> ();
67 char* buf = xercesc::XMLString::transcode (s);
69 std::basic_string<char> r (buf);
71 xercesc::XMLString::release (&buf);
73 return r;
76 template <>
77 inline
78 std::basic_string<wchar_t>
79 transcode<wchar_t> (XMLCh const* s, wchar_t*)
81 if (s == 0) return std::basic_string<wchar_t> ();
83 // std::wcerr << s << std::endl;
85 std::basic_string<wchar_t> r (xercesc::XMLString::stringLen (s), L'0');
87 for (std::size_t i (0); *s != XMLCh (0); ++s, ++i)
89 r[i] = *s;
92 return r;
95 template <>
96 inline
97 XMLCh*
98 transcode (std::basic_string<char> const& s)
100 return xercesc::XMLString::transcode (s.c_str ());
103 template <>
104 inline
105 XMLCh*
106 transcode (std::basic_string<wchar_t> const& s)
108 //@@ VC6
109 std::size_t l = s.length ();
111 //@@ VC6
112 XMLCh* r = new XMLCh[l + 1];
113 XMLCh* ir = r;
115 for (std::size_t i (0); i < l; ++ir, ++i)
117 *ir = static_cast<XMLCh>(s[i]);
118 //std::wcerr << s[i] << "->" << *ir << std::endl;
121 *ir = XMLCh (0);
123 // std::wcerr << r << std::endl;
125 return r;
129 template <typename C>
130 class Element;
132 template <typename C>
133 std::basic_string<C>
134 ns_prefix (std::basic_string<C> const& ns, Element<C> const& e);
136 // Casting helpers, made necessary by the Xerces project's braindead
137 // avoidance of RTTI.
138 template <typename DERIVED> struct dom_traits;
140 // Specializations for different node types
141 template <>
142 struct dom_traits<xercesc::DOMElement *>
144 static const xercesc::DOMNode::NodeType node_type = xercesc::DOMNode::ELEMENT_NODE;
147 template <>
148 struct dom_traits<xercesc::DOMAttr *>
150 static const xercesc::DOMNode::NodeType node_type = xercesc::DOMNode::ATTRIBUTE_NODE;
153 template <typename DERIVED_PTR>
154 DERIVED_PTR dom_cast (xercesc::DOMNode *node)
156 DERIVED_PTR elem = 0;
157 if ((node != 0) &&
158 (node->getNodeType () == dom_traits<DERIVED_PTR>::node_type))
160 elem = reinterpret_cast <DERIVED_PTR> (node);
162 return elem;
165 template <typename C>
166 class Element
168 typedef std::basic_string<C> string_;
170 public:
171 Element (xercesc::DOMElement const* e)
172 : e_ (0),
173 ce_ (e),
174 name_ (transcode<C> (e->getLocalName (), 0)),
175 namespace__ (transcode<C> (e->getNamespaceURI (), 0))
179 Element (xercesc::DOMElement* e)
180 : e_ (e),
181 ce_ (e),
182 name_ (transcode<C> (e->getLocalName (), 0)),
183 namespace__ (transcode<C> (e->getNamespaceURI (), 0))
187 Element (string_ const& name, Element& parent)
188 : e_ (0),
189 ce_ (0),
190 name_ (name)
192 xercesc::DOMDocument* doc (
193 parent.dom_element ()->getOwnerDocument ());
195 e_ = doc->createElement (string (name).c_str ());
197 parent.dom_element ()->appendChild (e_);
199 ce_ = e_;
202 Element (string_ const& name, string_ const& ns, Element& parent)
203 : e_ (0),
204 ce_ (0),
205 name_ (name),
206 namespace__ (ns)
208 string_ prefix (ns_prefix (ns, parent));
210 xercesc::DOMDocument* doc (
211 parent.dom_element ()->getOwnerDocument ());
213 e_ = doc->createElementNS (
214 string (ns).c_str (),
215 string (prefix.empty ()
216 ? name
217 : prefix + string_ (1, ':') + name).c_str ());
219 parent.dom_element ()->appendChild (e_);
221 ce_ = e_;
224 public:
225 string_
226 name () const
228 return name_;
231 string_
232 namespace_ () const
234 return namespace__;
237 public:
238 Element<C>
239 parent () const
241 return dom_cast <xercesc::DOMElement const*>(ce_->getParentNode ());
244 public:
245 string_
246 value () const
248 return XML::transcode<C> (dom_element ()->getTextContent (), 0);
251 void
252 value (string_ const& v)
254 xercesc::DOMText* text (
255 dom_element ()->getOwnerDocument ()->createTextNode(
256 string (v).c_str ()));
258 dom_element ()->appendChild (text);
261 public:
262 string_
263 operator[] (string_ const& s) const
265 //@@ VC6
266 XMLCh const* value = ce_->getAttribute (string (s).c_str ());
268 return transcode<C> (value, 0);
271 public:
272 xercesc::DOMElement const*
273 dom_element () const
275 return ce_;
278 xercesc::DOMElement*
279 dom_element ()
281 return e_;
284 private:
285 xercesc::DOMElement* e_;
286 xercesc::DOMElement const* ce_;
288 string_ name_;
289 string_ namespace__;
293 template <typename C>
294 class Attribute
296 typedef std::basic_string<C> string_;
298 public:
299 Attribute (xercesc::DOMAttr const* a)
300 : a_ (0),
301 ca_ (a),
302 name_ (transcode<C> (a->getLocalName (), 0)),
303 value_ (transcode<C> (a->getValue (), 0))
307 Attribute (xercesc::DOMAttr* a)
308 : a_ (a),
309 ca_ (a),
310 name_ (transcode<C> (a->getLocalName (), 0)),
311 value_ (transcode<C> (a->getValue (), 0))
315 Attribute (string_ const& name,
316 string_ const& v,
317 Element<C>& parent)
318 : a_ (0),
319 ca_ (0),
320 name_ (name),
321 value_ ()
323 xercesc::DOMDocument* doc (
324 parent.dom_element ()->getOwnerDocument ());
326 a_ = doc->createAttribute (string (name).c_str ());
328 value (v);
330 parent.dom_element ()->setAttributeNode (a_);
332 ca_ = a_;
335 Attribute (string_ const& name,
336 string_ const& ns,
337 string_ const& v,
338 Element<C>& parent)
339 : a_ (0),
340 ca_ (0),
341 name_ (name),
342 value_ ()
344 string_ prefix (ns_prefix (ns, parent));
346 xercesc::DOMDocument* doc (
347 parent.dom_element ()->getOwnerDocument ());
349 a_ = doc->createAttributeNS (
350 string (ns).c_str (),
351 string (prefix.empty ()
352 ? name
353 : prefix + string_ (1, ':') + name).c_str ());
355 value (v);
357 parent.dom_element ()->setAttributeNodeNS (a_);
359 ca_ = a_;
362 string_
363 name () const
365 return name_;
368 string_
369 value () const
371 return value_;
374 void
375 value (string_ const& v)
377 value_ = v;
378 a_->setValue (string (v).c_str ());
381 public:
382 xercesc::DOMAttr const*
383 dom_attribute () const
385 return ca_;
388 xercesc::DOMAttr*
389 dom_attribute ()
391 return a_;
394 private:
396 private:
397 xercesc::DOMAttr* a_;
398 xercesc::DOMAttr const* ca_;
400 string_ name_;
401 string_ value_;
404 template <typename C>
405 std::basic_string<C>
406 prefix (std::basic_string<C> const& n)
408 std::size_t i (0);
409 while (i < n.length () && n[i] != ':') ++i;
411 //std::wcerr << "prefix " << n << " "
412 // << std::wstring (n, i == n.length () ? i : 0, i) << std::endl;
414 return std::basic_string<C> (n, i == n.length () ? i : 0, i);
417 template <typename C>
418 std::basic_string<C>
419 uq_name (std::basic_string<C> const& n)
421 std::size_t i (0);
422 while (i < n.length () && n[i] != ':') ++i;
424 return std::basic_string<C> (n.c_str () + (i == n.length () ? 0 : i + 1));
427 template <typename C>
428 std::basic_string<C>
429 ns_name (Element<C> const& e, std::basic_string<C> const& n)
431 std::basic_string<C> wp (prefix (n));
433 //@@ VC6
434 XMLCh const* xns = e.dom_element ()->lookupNamespaceURI (
435 wp.empty () ? 0 : string (wp).c_str ());
438 std::basic_string<C> ns (
439 xns ? transcode<C> (xns, 0) : std::basic_string<C> ());
441 return ns;
445 template <typename C>
446 std::basic_string<C>
447 fq_name (Element<C> const& e, std::basic_string<C> const& n)
449 std::basic_string<C> ns (ns_name (e, n));
450 std::basic_string<C> un (uq_name (n));
452 return ns.empty () ? un : (ns + C ('#') + un);
455 class no_prefix {};
457 template <typename C>
458 std::basic_string<C>
459 ns_prefix (std::basic_string<C> const& ns, Element<C> const& e)
461 string xns (ns);
463 XMLCh const* p (e.dom_element ()->lookupPrefix (xns.c_str ()));
465 if (p == 0)
467 bool const r (e.dom_element ()->isDefaultNamespace (xns.c_str ()));
469 if (r)
471 return std::basic_string<C> ();
473 else
475 throw no_prefix ();
479 return transcode<C> (p, 0);
484 #endif // XSCRT_XML_HPP