1 // file : XSCRT/XML.hpp
2 // author : Boris Kolpackov <boris@dre.vanderbilt.edu>
9 #include <xercesc/dom/DOM.hpp>
10 #include <xercesc/util/XMLString.hpp>
20 transcode (XMLCh
const* s
, C
*);
24 transcode (std::basic_string
<C
> const& s
);
33 string (std::basic_string
<C
> const& s
)
34 : s_ (XSCRT::XML::transcode
<C
> (s
))
40 : s_ (XSCRT::XML::transcode
<C
> (s
))
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
);
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
)
98 transcode (std::basic_string
<char> const& s
)
100 return xercesc::XMLString::transcode (s
.c_str ());
106 transcode (std::basic_string
<wchar_t> const& s
)
109 std::size_t l
= s
.length ();
112 XMLCh
* r
= new XMLCh
[l
+ 1];
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;
123 // std::wcerr << r << std::endl;
129 template <typename C
>
132 template <typename 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
142 struct dom_traits
<xercesc::DOMElement
*>
144 static const xercesc::DOMNode::NodeType node_type
= xercesc::DOMNode::ELEMENT_NODE
;
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;
158 (node
->getNodeType () == dom_traits
<DERIVED_PTR
>::node_type
))
160 elem
= reinterpret_cast <DERIVED_PTR
> (node
);
165 template <typename C
>
168 typedef std::basic_string
<C
> string_
;
171 Element (xercesc::DOMElement
const* e
)
174 name_ (transcode
<C
> (e
->getLocalName (), 0)),
175 namespace__ (transcode
<C
> (e
->getNamespaceURI (), 0))
179 Element (xercesc::DOMElement
* e
)
182 name_ (transcode
<C
> (e
->getLocalName (), 0)),
183 namespace__ (transcode
<C
> (e
->getNamespaceURI (), 0))
187 Element (string_
const& name
, Element
& parent
)
192 xercesc::DOMDocument
* doc (
193 parent
.dom_element ()->getOwnerDocument ());
195 e_
= doc
->createElement (string (name
).c_str ());
197 parent
.dom_element ()->appendChild (e_
);
202 Element (string_
const& name
, string_
const& ns
, Element
& parent
)
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 ()
217 : prefix
+ string_ (1, ':') + name
).c_str ());
219 parent
.dom_element ()->appendChild (e_
);
241 return dom_cast
<xercesc::DOMElement
const*>(ce_
->getParentNode ());
248 return XML::transcode
<C
> (dom_element ()->getTextContent (), 0);
252 value (string_
const& v
)
254 xercesc::DOMText
* text (
255 dom_element ()->getOwnerDocument ()->createTextNode(
256 string (v
).c_str ()));
258 dom_element ()->appendChild (text
);
263 operator[] (string_
const& s
) const
266 XMLCh
const* value
= ce_
->getAttribute (string (s
).c_str ());
268 return transcode
<C
> (value
, 0);
272 xercesc::DOMElement
const*
285 xercesc::DOMElement
* e_
;
286 xercesc::DOMElement
const* ce_
;
293 template <typename C
>
296 typedef std::basic_string
<C
> string_
;
299 Attribute (xercesc::DOMAttr
const* a
)
302 name_ (transcode
<C
> (a
->getLocalName (), 0)),
303 value_ (transcode
<C
> (a
->getValue (), 0))
307 Attribute (xercesc::DOMAttr
* a
)
310 name_ (transcode
<C
> (a
->getLocalName (), 0)),
311 value_ (transcode
<C
> (a
->getValue (), 0))
315 Attribute (string_
const& name
,
323 xercesc::DOMDocument
* doc (
324 parent
.dom_element ()->getOwnerDocument ());
326 a_
= doc
->createAttribute (string (name
).c_str ());
330 parent
.dom_element ()->setAttributeNode (a_
);
335 Attribute (string_
const& name
,
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 ()
353 : prefix
+ string_ (1, ':') + name
).c_str ());
357 parent
.dom_element ()->setAttributeNodeNS (a_
);
375 value (string_
const& v
)
378 a_
->setValue (string (v
).c_str ());
382 xercesc::DOMAttr
const*
383 dom_attribute () const
397 xercesc::DOMAttr
* a_
;
398 xercesc::DOMAttr
const* ca_
;
404 template <typename C
>
406 prefix (std::basic_string
<C
> const& n
)
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
>
419 uq_name (std::basic_string
<C
> const& n
)
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
>
429 ns_name (Element
<C
> const& e
, std::basic_string
<C
> const& n
)
431 std::basic_string
<C
> wp (prefix (n
));
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
> ());
445 template <typename 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
);
457 template <typename C
>
459 ns_prefix (std::basic_string
<C
> const& ns
, Element
<C
> const& e
)
463 XMLCh
const* p (e
.dom_element ()->lookupPrefix (xns
.c_str ()));
467 bool const r (e
.dom_element ()->isDefaultNamespace (xns
.c_str ()));
471 return std::basic_string
<C
> ();
479 return transcode
<C
> (p
, 0);
484 #endif // XSCRT_XML_HPP