root/win32/xsd-3.1.0-i686/libxsd/xsd/cxx/xml/dom/serialization-source.txx @ 111

Revision 111, 12.5 kB (checked in by mido, 16 years ago)

pridana knihovna XSD (a jeji chlebodarkyne XERCES), v ramci Win32 zprovoznen priklad tests/test_xsd_hello.cxx

Line 
1// file      : xsd/cxx/xml/dom/serialization-source.txx
2// author    : Boris Kolpackov <boris@codesynthesis.com>
3// copyright : Copyright (c) 2005-2008 Code Synthesis Tools CC
4// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file
5
6#include <xercesc/util/XMLUni.hpp>     // xercesc::fg*
7#include <xercesc/util/XMLUniDefs.hpp> // chLatin_L, etc
8
9#if _XERCES_VERSION >= 30000
10#  include <xercesc/dom/DOMLSOutput.hpp>
11#  include <xercesc/dom/DOMLSSerializer.hpp>
12#else
13#  include <xercesc/dom/DOMWriter.hpp>
14#endif
15#include <xercesc/dom/DOMElement.hpp>
16#include <xercesc/dom/DOMImplementation.hpp>
17#include <xercesc/dom/DOMImplementationRegistry.hpp>
18
19#include <xsd/cxx/xml/string.hxx>
20#include <xsd/cxx/xml/bits/literals.hxx>
21#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
22
23namespace xsd
24{
25  namespace cxx
26  {
27    namespace xml
28    {
29      namespace dom
30      {
31        //
32        //
33        template <typename C>
34        xercesc::DOMAttr&
35        create_attribute (const C* name, xercesc::DOMElement& parent)
36        {
37          xercesc::DOMDocument* doc (parent.getOwnerDocument ());
38          xercesc::DOMAttr* a (doc->createAttribute (string (name).c_str ()));
39          parent.setAttributeNode (a);
40          return *a;
41        }
42
43        template <typename C>
44        xercesc::DOMAttr&
45        create_attribute (const C* name,
46                          const C* ns,
47                          xercesc::DOMElement& parent)
48        {
49          if (ns[0] == C ('\0'))
50            return create_attribute (name, parent);
51
52          xercesc::DOMDocument* doc (parent.getOwnerDocument ());
53
54          xercesc::DOMAttr* a;
55          std::basic_string<C> p (prefix<C> (ns, parent));
56
57          if (!p.empty ())
58          {
59            p += ':';
60            p += name;
61            a = doc->createAttributeNS (string (ns).c_str (),
62                                        string (p).c_str ());
63          }
64          else
65            a = doc->createAttributeNS (string (ns).c_str (),
66                                        string (name).c_str ());
67
68          parent.setAttributeNodeNS (a);
69          return *a;
70        }
71
72        template <typename C>
73        xercesc::DOMElement&
74        create_element (const C* name, xercesc::DOMElement& parent)
75        {
76          xercesc::DOMDocument* doc (parent.getOwnerDocument ());
77          xercesc::DOMElement* e (doc->createElement (string (name).c_str ()));
78          parent.appendChild (e);
79          return *e;
80        }
81
82        template <typename C>
83        xercesc::DOMElement&
84        create_element (const C* name,
85                        const C* ns,
86                        xercesc::DOMElement& parent)
87        {
88          if (ns[0] == C ('\0'))
89            return create_element (name, parent);
90
91          xercesc::DOMDocument* doc (parent.getOwnerDocument ());
92
93          xercesc::DOMElement* e;
94          std::basic_string<C> p (prefix<C> (ns, parent));
95
96          if (!p.empty ())
97          {
98            p += ':';
99            p += name;
100            e = doc->createElementNS (string (ns).c_str (),
101                                      string (p).c_str ());
102          }
103          else
104            e = doc->createElementNS (string (ns).c_str (),
105                                      string (name).c_str ());
106
107          parent.appendChild (e);
108          return *e;
109        }
110
111
112        //
113        //
114        template <typename C>
115        auto_ptr<xercesc::DOMDocument>
116        serialize (const std::basic_string<C>& el,
117                   const std::basic_string<C>& ns,
118                   const namespace_infomap<C>& map,
119                   unsigned long)
120        {
121          // HP aCC cannot handle using namespace xercesc;
122          //
123          using xercesc::DOMImplementationRegistry;
124          using xercesc::DOMImplementation;
125          using xercesc::DOMDocument;
126          using xercesc::DOMElement;
127
128          //
129          //
130          typedef std::basic_string<C> string;
131          typedef namespace_infomap<C> infomap;
132          typedef typename infomap::const_iterator infomap_iterator;
133
134          C colon (':'), space (' ');
135
136          string prefix;
137
138          if (!ns.empty ())
139          {
140            infomap_iterator i (map.begin ()), e (map.end ());
141
142            for ( ;i != e; ++i)
143            {
144              if (i->second.name == ns)
145              {
146                prefix = i->first;
147                break;
148              }
149            }
150
151            if (i == e)
152              throw mapping<C> (ns);
153          }
154
155          const XMLCh ls[] = {xercesc::chLatin_L,
156                              xercesc::chLatin_S,
157                              xercesc::chNull};
158
159          DOMImplementation* impl (
160            DOMImplementationRegistry::getDOMImplementation (ls));
161
162          auto_ptr<DOMDocument> doc (
163            impl->createDocument (
164              (ns.empty () ? 0 : xml::string (ns).c_str ()),
165              xml::string ((prefix.empty ()
166                            ? el
167                            : prefix + colon + el)).c_str (),
168              0));
169
170          DOMElement* root (doc->getDocumentElement ());
171
172          // Check if we need to provide xsi mapping.
173          //
174          bool xsi (false);
175          string xsi_prefix (xml::bits::xsi_prefix<C> ());
176          string xmlns_prefix (xml::bits::xmlns_prefix<C> ());
177
178          for (infomap_iterator i (map.begin ()), e (map.end ()); i != e; ++i)
179          {
180            if (!i->second.schema.empty ())
181            {
182              xsi = true;
183              break;
184            }
185          }
186
187          // Check if we were told to provide xsi mapping.
188          //
189          if (xsi)
190          {
191            for (infomap_iterator i (map.begin ()), e (map.end ());
192                 i != e;
193                 ++i)
194            {
195              if (i->second.name == xml::bits::xsi_namespace<C> ())
196              {
197                xsi_prefix = i->first;
198                xsi = false;
199                break;
200              }
201            }
202
203            if (xsi)
204            {
205              // If we were not told to provide xsi mapping, make sure our
206              // prefix does not conflict with user-defined prefixes.
207              //
208              infomap_iterator i (map.find (xsi_prefix));
209
210              if (i != map.end ())
211                throw xsi_already_in_use ();
212            }
213          }
214
215          // Create xmlns:xsi attribute.
216          //
217          if (xsi)
218          {
219            root->setAttributeNS (
220              xml::string (xml::bits::xmlns_namespace<C> ()).c_str (),
221              xml::string (xmlns_prefix + colon + xsi_prefix).c_str (),
222              xml::string (xml::bits::xsi_namespace<C> ()).c_str ());
223          }
224
225
226          // Create user-defined mappings.
227          //
228          for (infomap_iterator i (map.begin ()), e (map.end ()); i != e; ++i)
229          {
230            if (i->first.empty ())
231            {
232              // Empty prefix.
233              //
234              if (!i->second.name.empty ())
235                root->setAttributeNS (
236                  xml::string (xml::bits::xmlns_namespace<C> ()).c_str (),
237                  xml::string (xmlns_prefix).c_str (),
238                  xml::string (i->second.name).c_str ());
239            }
240            else
241            {
242              root->setAttributeNS (
243                xml::string (xml::bits::xmlns_namespace<C> ()).c_str (),
244                xml::string (xmlns_prefix + colon + i->first).c_str (),
245                xml::string (i->second.name).c_str ());
246            }
247          }
248
249          // Create xsi:schemaLocation and xsi:noNamespaceSchemaLocation
250          // attributes.
251          //
252          string schema_location;
253          string no_namespace_schema_location;
254
255          for (infomap_iterator i (map.begin ()), e (map.end ()); i != e; ++i)
256          {
257            if (!i->second.schema.empty ())
258            {
259              if (i->second.name.empty ())
260              {
261                if (!no_namespace_schema_location.empty ())
262                  no_namespace_schema_location += space;
263
264                no_namespace_schema_location += i->second.schema;
265              }
266              else
267              {
268                if (!schema_location.empty ())
269                  schema_location += space;
270
271                schema_location += i->second.name + space + i->second.schema;
272              }
273            }
274          }
275
276          if (!schema_location.empty ())
277          {
278            root->setAttributeNS (
279              xml::string (xml::bits::xsi_namespace<C> ()).c_str (),
280              xml::string (xsi_prefix + colon +
281                           xml::bits::schema_location<C> ()).c_str (),
282              xml::string (schema_location).c_str ());
283          }
284
285          if (!no_namespace_schema_location.empty ())
286          {
287            root->setAttributeNS (
288              xml::string (xml::bits::xsi_namespace<C> ()).c_str (),
289              xml::string (
290                xsi_prefix + colon +
291                xml::bits::no_namespace_schema_location<C> ()).c_str (),
292              xml::string (no_namespace_schema_location).c_str ());
293          }
294
295          return doc;
296        }
297
298
299        template <typename C>
300        bool
301        serialize (xercesc::XMLFormatTarget& target,
302                   const xercesc::DOMDocument& doc,
303                   const std::basic_string<C>& encoding,
304                   xercesc::DOMErrorHandler& eh,
305                   unsigned long flags)
306        {
307          // HP aCC cannot handle using namespace xercesc;
308          //
309          using xercesc::DOMImplementationRegistry;
310          using xercesc::DOMImplementation;
311#if _XERCES_VERSION >= 30000
312          using xercesc::DOMLSSerializer;
313          using xercesc::DOMConfiguration;
314          using xercesc::DOMLSOutput;
315#else
316          using xercesc::DOMWriter;
317#endif
318          using xercesc::XMLUni;
319
320          const XMLCh ls[] = {xercesc::chLatin_L,
321                              xercesc::chLatin_S,
322                              xercesc::chNull};
323
324          DOMImplementation* impl (
325            DOMImplementationRegistry::getDOMImplementation (ls));
326
327          bits::error_handler_proxy<C> ehp (eh);
328
329#if _XERCES_VERSION >= 30000
330          xml::dom::auto_ptr<DOMLSSerializer> writer (
331            impl->createLSSerializer ());
332
333          DOMConfiguration* conf (writer->getDomConfig ());
334
335          conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
336
337          // Set some nice features if the serializer supports them.
338          //
339          if (conf->canSetParameter (
340                XMLUni::fgDOMWRTDiscardDefaultContent, true))
341            conf->setParameter (XMLUni::fgDOMWRTDiscardDefaultContent, true);
342
343          if (conf->canSetParameter (XMLUni::fgDOMWRTFormatPrettyPrint, true))
344            conf->setParameter (XMLUni::fgDOMWRTFormatPrettyPrint, true);
345
346          // See if we need to write XML declaration.
347          //
348          if ((flags & no_xml_declaration) &&
349              conf->canSetParameter (XMLUni::fgDOMXMLDeclaration, false))
350            conf->setParameter (XMLUni::fgDOMXMLDeclaration, false);
351
352          xml::dom::auto_ptr<DOMLSOutput> out (impl->createLSOutput ());
353
354          out->setEncoding (xml::string (encoding).c_str ());
355          out->setByteStream (&target);
356
357          bool r (writer->write (&doc, out.get ()));
358#else
359          xml::dom::auto_ptr<DOMWriter> writer (impl->createDOMWriter ());
360
361          writer->setErrorHandler (&ehp);
362          writer->setEncoding (xml::string (encoding).c_str ());
363
364          // Set some nice features if the serializer supports them.
365          //
366          if (writer->canSetFeature (
367                XMLUni::fgDOMWRTDiscardDefaultContent, true))
368            writer->setFeature (XMLUni::fgDOMWRTDiscardDefaultContent, true);
369
370          if (writer->canSetFeature (XMLUni::fgDOMWRTFormatPrettyPrint, true))
371            writer->setFeature (XMLUni::fgDOMWRTFormatPrettyPrint, true);
372
373          // See if we need to write XML declaration.
374          //
375          if ((flags & no_xml_declaration) &&
376              writer->canSetFeature (XMLUni::fgDOMXMLDeclaration, false))
377            writer->setFeature (XMLUni::fgDOMXMLDeclaration, false);
378
379          bool r (writer->writeNode (&target, doc));
380#endif
381
382          if (!r || ehp.failed ())
383            return false;
384
385          return true;
386        }
387
388        template <typename C>
389        bool
390        serialize (xercesc::XMLFormatTarget& target,
391                   const xercesc::DOMDocument& doc,
392                   const std::basic_string<C>& enconding,
393                   error_handler<C>& eh,
394                   unsigned long flags)
395        {
396          bits::error_handler_proxy<C> ehp (eh);
397          return serialize (target, doc, enconding, ehp, flags);
398        }
399      }
400    }
401  }
402}
Note: See TracBrowser for help on using the browser.