Line data Source code
1 : // file : xsd/cxx/xml/dom/serialization-header.txx
2 : // copyright : Copyright (c) 2005-2017 Code Synthesis Tools CC
3 : // license : GNU GPL v2 + exceptions; see accompanying LICENSE file
4 :
5 : #include <vector>
6 : #include <sstream>
7 : #include <cstddef> // std::size_t
8 :
9 : #include <xercesc/dom/DOMNode.hpp>
10 : #include <xercesc/dom/DOMAttr.hpp>
11 : #include <xercesc/dom/DOMNamedNodeMap.hpp>
12 :
13 : #include <xercesc/util/XMLUni.hpp> // xercesc::fg*
14 : #include <xercesc/util/XMLString.hpp>
15 : #include <xercesc/validators/schema/SchemaSymbols.hpp>
16 :
17 : #include <xsd/cxx/xml/string.hxx>
18 : #include <xsd/cxx/xml/bits/literals.hxx>
19 :
20 : namespace xsd
21 : {
22 : namespace cxx
23 : {
24 : namespace xml
25 : {
26 : namespace dom
27 : {
28 : //
29 : //
30 : template <typename C>
31 : std::basic_string<C>
32 0 : prefix (const C* ns, xercesc::DOMElement& e, const C* hint)
33 : {
34 0 : string xns (ns);
35 0 : const XMLCh* p (e.lookupPrefix (xns.c_str ()));
36 :
37 0 : if (p != 0)
38 0 : return transcode<C> (p);
39 :
40 0 : if (e.isDefaultNamespace (xns.c_str ()))
41 0 : return std::basic_string<C> ();
42 :
43 : // 'xml' prefix requires special handling and Xerces folks
44 : // refuse to handle this in DOM so I have to do it myself.
45 : //
46 0 : if (std::basic_string<C> (ns) == xml::bits::xml_namespace<C> ())
47 0 : return xml::bits::xml_prefix<C> ();
48 :
49 : // No prefix for this namespace. Will need to establish one.
50 : //
51 0 : std::basic_string<C> prefix;
52 :
53 0 : if (hint != 0 &&
54 0 : e.lookupNamespaceURI (xml::string (hint).c_str ()) == 0)
55 : {
56 0 : prefix = hint;
57 : }
58 : else
59 : {
60 0 : for (unsigned long n (1);; ++n)
61 : {
62 : // Make finding the first few prefixes fast.
63 : //
64 0 : switch (n)
65 : {
66 0 : case 1:
67 : {
68 0 : prefix = xml::bits::first_prefix<C> ();
69 0 : break;
70 : }
71 0 : case 2:
72 : {
73 0 : prefix = xml::bits::second_prefix<C> ();
74 0 : break;
75 : }
76 0 : case 3:
77 : {
78 0 : prefix = xml::bits::third_prefix<C> ();
79 0 : break;
80 : }
81 0 : case 4:
82 : {
83 0 : prefix = xml::bits::fourth_prefix<C> ();
84 0 : break;
85 : }
86 0 : case 5:
87 : {
88 0 : prefix = xml::bits::fifth_prefix<C> ();
89 0 : break;
90 : }
91 0 : default:
92 : {
93 0 : std::basic_ostringstream<C> ostr;
94 0 : ostr << C ('p') << n;
95 0 : prefix = ostr.str ();
96 0 : break;
97 0 : }
98 : }
99 :
100 0 : if (e.lookupNamespaceURI (xml::string (prefix).c_str ()) == 0)
101 0 : break;
102 : }
103 : }
104 :
105 0 : std::basic_string<C> name (xml::bits::xmlns_prefix<C> ());
106 0 : name += C(':');
107 0 : name += prefix;
108 :
109 0 : e.setAttributeNS (
110 : xercesc::XMLUni::fgXMLNSURIName,
111 0 : xml::string (name).c_str (),
112 : xns.c_str ());
113 :
114 0 : return prefix;
115 0 : }
116 :
117 : //
118 : //
119 : template <typename C>
120 : void
121 0 : clear (xercesc::DOMElement& e)
122 : {
123 : // Cannot use 'using namespace' because of MSXML conflict.
124 : //
125 : using xercesc::XMLUni;
126 : using xercesc::XMLString;
127 : using xercesc::SchemaSymbols;
128 :
129 : using xercesc::DOMNode;
130 : using xercesc::DOMAttr;
131 : using xercesc::DOMNamedNodeMap;
132 :
133 : // Remove child nodes.
134 : //
135 0 : while (DOMNode* n = e.getFirstChild ())
136 : {
137 0 : e.removeChild (n);
138 0 : n->release ();
139 : }
140 :
141 : // Remove attributes.
142 : //
143 0 : DOMNamedNodeMap* att_map (e.getAttributes ());
144 0 : XMLSize_t n (att_map->getLength ());
145 :
146 0 : if (n != 0)
147 : {
148 0 : std::vector<DOMAttr*> atts;
149 :
150 : // Collect all attributes to be removed while filtering
151 : // out special cases (xmlns & xsi).
152 : //
153 0 : for (XMLSize_t i (0); i != n; ++i)
154 : {
155 0 : DOMAttr* a (static_cast<DOMAttr*> (att_map->item (i)));
156 0 : const XMLCh* ns (a->getNamespaceURI ());
157 :
158 0 : if (ns != 0)
159 : {
160 0 : if (XMLString::equals (ns, XMLUni::fgXMLNSURIName))
161 0 : continue;
162 :
163 0 : if (XMLString::equals (ns, SchemaSymbols::fgURI_XSI))
164 : {
165 0 : const XMLCh* name (a->getLocalName ());
166 :
167 0 : if (XMLString::equals (
168 0 : name, SchemaSymbols::fgXSI_SCHEMALOCACTION) ||
169 0 : XMLString::equals (
170 : name, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCACTION))
171 0 : continue;
172 : }
173 : }
174 :
175 0 : atts.push_back (a);
176 : }
177 :
178 0 : for (std::vector<DOMAttr*>::iterator i (atts.begin ()),
179 0 : end (atts.end ()); i != end; ++i)
180 : {
181 0 : e.removeAttributeNode (*i);
182 0 : (*i)->release ();
183 : }
184 0 : }
185 0 : }
186 : }
187 : }
188 : }
189 : }
|