1
2
3
4
5
6 #include <sngxml/dom/Node.hpp>
7 #include <sngxml/dom/Document.hpp>
8 #include <sngxml/dom/DocumentFragment.hpp>
9 #include <sngxml/dom/Exception.hpp>
10 #include <algorithm>
11
12 namespace sngxml { namespace dom {
13
14 NodeOp::~NodeOp()
15 {
16 }
17
18 void NodeOp::Apply(Node* node)
19 {
20 }
21
22 std::u32string AxisName(Axis axis)
23 {
24 switch (axis)
25 {
26 case Axis::child: return U"child";
27 case Axis::descendant: return U"descendant";
28 case Axis::parent: return U"parent";
29 case Axis::ancestor: return U"ancestor";
30 case Axis::followingSibling: return U"followingSibling";
31 case Axis::precedingSibling: return U"precedingSibling";
32 case Axis::following: return U"following";
33 case Axis::preceding: return U"preceding";
34 case Axis::attribute: return U"attribute";
35 case Axis::ns: return U"namespace";
36 case Axis::self: return U"self";
37 case Axis::descendantOrSelf: return U"descendantOrSelf";
38 case Axis::ancestorOrSelf: return U"ancestorOrSelf";
39 }
40 return std::u32string();
41 }
42
43 Node::Node(NodeType nodeType_, const std::u32string& name_) : nodeType(nodeType_), name(name_), parent(nullptr), previousSibling(nullptr), nextSibling(nullptr), ownerDocument(nullptr)
44 {
45 }
46
47 Node::~Node()
48 {
49 }
50
51 std::u32string Node::Prefix() const
52 {
53 if (nodeType == NodeType::elementNode || nodeType == NodeType::attributeNode)
54 {
55 auto colonPos = name.find(':');
56 if (colonPos != std::u32string::npos)
57 {
58 return name.substr(0, colonPos);
59 }
60 }
61 return std::u32string();
62 }
63
64 void Node::SetPrefix(const std::u32string& prefix)
65 {
66 if (nodeType == NodeType::elementNode || nodeType == NodeType::attributeNode)
67 {
68 auto colonPos = name.find(':');
69 if (prefix.empty())
70 {
71 if (colonPos != std::u32string::npos)
72 {
73 name = name.substr(colonPos + 1);
74 }
75 }
76 else
77 {
78 if (colonPos != std::u32string::npos)
79 {
80 name = prefix + U":" + name.substr(colonPos + 1);
81 }
82 else
83 {
84 name = prefix + U":" + name;
85 }
86 }
87 }
88 else
89 {
90 throw DomException("cannot set prefix for this node type");
91 }
92 }
93
94 std::u32string Node::LocalName() const
95 {
96 if (nodeType == NodeType::elementNode || nodeType == NodeType::attributeNode)
97 {
98 auto colonPos = name.find(':');
99 if (colonPos != std::u32string::npos)
100 {
101 return name.substr(colonPos + 1);
102 }
103 else
104 {
105 return name;
106 }
107 }
108 else
109 {
110 return std::u32string();
111 }
112 }
113
114 void Node::Walk(NodeOp& nodeOp, Axis axis)
115 {
116 switch (axis)
117 {
118 case Axis::child: WalkChildren(nodeOp); break;
119 case Axis::descendant: WalkDescendant(nodeOp); break;
120 case Axis::descendantOrSelf: WalkDescendantOrSelf(nodeOp); break;
121 case Axis::parent: WalkParent(nodeOp); break;
122 case Axis::ancestor: WalkAncestor(nodeOp); break;
123 case Axis::ancestorOrSelf: WalkAncestorOrSelf(nodeOp); break;
124 case Axis::followingSibling: WalkFollowingSibling(nodeOp); break;
125 case Axis::precedingSibling: WalkPrecedingSibling(nodeOp); break;
126 case Axis::following: WalkFollowing(nodeOp); break;
127 case Axis::preceding: WalkPreceding(nodeOp); break;
128 case Axis::attribute: WalkAttribute(nodeOp); break;
129 case Axis::self: nodeOp.Apply(this); break;
130 }
131 }
132
133 void Node::WalkChildren(NodeOp& nodeOp)
134 {
135 }
136
137 void Node::WalkDescendant(NodeOp& nodeOp)
138 {
139 }
140
141 void Node::WalkDescendantOrSelf(NodeOp& nodeOp)
142 {
143 nodeOp.Apply(this);
144 }
145
146 void Node::WalkParent(NodeOp& nodeOp)
147 {
148 if (parent)
149 {
150 nodeOp.Apply(parent);
151 }
152 }
153
154 void Node::WalkFollowing(NodeOp& nodeOp)
155 {
156 Node* ns = nextSibling;
157 if (ns)
158 {
159 ns->WalkDescendantOrSelf(nodeOp);
160 ns = ns->nextSibling;
161 }
162 }
163
164 void Node::WalkPreceding(NodeOp& nodeOp)
165 {
166 }
167
168 void Node::WalkPrecedingOrSelf(NodeOp& nodeOp)
169 {
170 nodeOp.Apply(this);
171 }
172
173 void Node::WalkAncestor(NodeOp& nodeOp)
174 {
175 if (parent)
176 {
177 parent->WalkAncestorOrSelf(nodeOp);
178 }
179 }
180
181 void Node::WalkAncestorOrSelf(NodeOp& nodeOp)
182 {
183 nodeOp.Apply(this);
184 if (parent)
185 {
186 parent->WalkAncestorOrSelf(nodeOp);
187 }
188 }
189
190 void Node::WalkFollowingSibling(NodeOp& nodeOp)
191 {
192 Node* ns = nextSibling;
193 if (ns)
194 {
195 nodeOp.Apply(ns);
196 ns = ns->nextSibling;
197 }
198 }
199
200 void Node::WalkPrecedingSibling(NodeOp& nodeOp)
201 {
202 Node* ps = previousSibling;
203 if (ps)
204 {
205 nodeOp.Apply(ps);
206 ps = ps->previousSibling;
207 }
208 }
209
210 void Node::WalkAttribute(NodeOp& nodeOp)
211 {
212 }
213
214 void Node::InternalLinkBefore(Node* newNode)
215 {
216 newNode->previousSibling = previousSibling;
217 newNode->nextSibling = this;
218 previousSibling = newNode;
219 }
220
221 void Node::InternalLinkAfter(Node* newNode)
222 {
223 newNode->previousSibling = this;
224 newNode->nextSibling = nextSibling;
225 nextSibling = newNode;
226 }
227
228 void Node::InternalUnlink()
229 {
230 if (previousSibling)
231 {
232 previousSibling->nextSibling = nextSibling;
233 }
234 if (nextSibling)
235 {
236 nextSibling->previousSibling = previousSibling;
237 }
238 }
239
240 void Node::InternalSetNamespaceUri(const std::u32string& namespaceUri_)
241 {
242 namespaceUri = namespaceUri_;
243 }
244
245 ParentNode::ParentNode(NodeType nodeType_, const std::u32string& name_) : Node(nodeType_, name_), firstChild(nullptr), lastChild(nullptr)
246 {
247 }
248
249 ParentNode::~ParentNode()
250 {
251 Node* child = firstChild;
252 while (child != nullptr)
253 {
254 Node* toDel = child;
255 child = child->NextSibling();
256 delete toDel;
257 }
258 }
259
260 NodeList ParentNode::ChildNodes() const
261 {
262 NodeList result;
263 Node* child = firstChild;
264 while (child != nullptr)
265 {
266 result.InternalAddNode(child);
267 child = child->NextSibling();
268 }
269 return result;
270 }
271
272 void ParentNode::Write(CodeFormatter& formatter)
273 {
274 Node* child = firstChild;
275 while (child != nullptr)
276 {
277 child->Write(formatter);
278 child = child->NextSibling();
279 }
280 }
281
282 void ParentNode::CloneChildrenTo(ParentNode* clone) const
283 {
284 Node* child = firstChild;
285 while (child != nullptr)
286 {
287 clone->AppendChild(child->CloneNode(true));
288 child = child->NextSibling();
289 }
290 }
291
292 Node* ParentNode::InsertBefore(std::std::unique_ptr<Node>&&newChild, Node*refChild)
293 {
294 if (refChild == nullptr)
295 {
296 return AppendChild(std::move(newChild));
297 }
298 else
299 {
300 if (OwnerDocument())
301 {
302 OwnerDocument()->InternalInvalidateIndex();
303 }
304 if (newChild->GetNodeType() == NodeType::documentFragmentNode)
305 {
306 DocumentFragment* documentFragment = static_cast<DocumentFragment*>(newChild.get());
307 Node* docFragChild = documentFragment->FirstChild();
308 Node* nodeInserted = nullptr;
309 while (docFragChild != nullptr)
310 {
311 std::unique_ptr<Node> docFragChildRemoved = documentFragment->RemoveChild(docFragChild);
312 nodeInserted = InsertBefore(std::move(docFragChildRemoved), refChild);
313 docFragChild = documentFragment->FirstChild();
314 }
315 return nodeInserted;
316 }
317 else
318 {
319 if (newChild->Parent())
320 {
321 newChild.reset(newChild->Parent()->RemoveChild(newChild.get()).release());
322 }
323 if (firstChild == refChild)
324 {
325 firstChild = newChild.get();
326 }
327 newChild->InternalSetParent(this);
328 newChild->InternalSetOwnerDocument(OwnerDocument());
329 Node* nodeInserted = newChild.get();
330 refChild->InternalLinkBefore(newChild.release());
331 return nodeInserted;
332 }
333 }
334 }
335
336 std::std::unique_ptr<Node>ParentNode::RemoveChild(Node*oldChild)
337 {
338 if (!oldChild)
339 {
340 throw DomException("could not remove node: given old child is null");
341 }
342 if (oldChild->Parent() != this)
343 {
344 throw DomException("could not remove node: given old child is not child of this node");
345 }
346 if (OwnerDocument())
347 {
348 OwnerDocument()->InternalInvalidateIndex();
349 }
350 oldChild->InternalUnlink();
351 if (oldChild == firstChild)
352 {
353 firstChild = oldChild->NextSibling();
354 }
355 if (oldChild == lastChild)
356 {
357 lastChild = oldChild->PreviousSibling();
358 }
359 std::unique_ptr<Node> removedNode = std::unique_ptr<Node>(oldChild);
360 removedNode->InternalSetOwnerDocument(nullptr);
361 removedNode->InternalSetParent(nullptr);
362 return removedNode;
363 }
364
365 std::std::unique_ptr<Node>ParentNode::ReplaceChild(std::std::unique_ptr<Node>&&newChild, Node*oldChild)
366 {
367 if (!oldChild)
368 {
369 throw DomException("could not replace node: given old child is null");
370 }
371 if (oldChild->Parent() != this)
372 {
373 throw DomException("could not replace node: given old child is not child of this node");
374 }
375 if (OwnerDocument())
376 {
377 OwnerDocument()->InternalInvalidateIndex();
378 }
379 if (newChild->Parent())
380 {
381 newChild.reset(newChild->Parent()->RemoveChild(newChild.get()).release());
382 }
383 InsertBefore(std::move(newChild), oldChild);
384 return RemoveChild(oldChild);
385 }
386
387 Node* ParentNode::AppendChild(std::std::unique_ptr<Node>&&newChild)
388 {
389 if (OwnerDocument())
390 {
391 OwnerDocument()->InternalInvalidateIndex();
392 }
393 if (newChild->Parent())
394 {
395 newChild.reset(newChild->Parent()->RemoveChild(newChild.get()).release());
396 }
397 if (newChild->GetNodeType() == NodeType::documentFragmentNode)
398 {
399 DocumentFragment* documentFragment = static_cast<DocumentFragment*>(newChild.get());
400 Node* docFragChild = documentFragment->FirstChild();
401 Node* nodeInserted = nullptr;
402 while (docFragChild != nullptr)
403 {
404 std::unique_ptr<Node> docFragChildRemoved = documentFragment->RemoveChild(docFragChild);
405 nodeInserted = AppendChild(std::move(docFragChildRemoved));
406 docFragChild = documentFragment->FirstChild();
407 }
408 return nodeInserted;
409 }
410 else
411 {
412 if (lastChild)
413 {
414 lastChild->InternalLinkAfter(newChild.get());
415 }
416 if (!firstChild)
417 {
418 firstChild = newChild.get();
419 }
420 newChild->InternalSetOwnerDocument(OwnerDocument());
421 newChild->InternalSetParent(this);
422 lastChild = newChild.release();
423 return lastChild;
424 }
425 }
426
427 void ParentNode::Accept(Visitor& visitor)
428 {
429 Node* child = firstChild;
430 while (child != nullptr)
431 {
432 child->Accept(visitor);
433 child = child->NextSibling();
434 }
435 }
436
437 void ParentNode::WalkChildren(NodeOp& nodeOp)
438 {
439 Node* child = firstChild;
440 while (child != nullptr)
441 {
442 nodeOp.Apply(child);
443 child = child->NextSibling();
444 }
445 }
446
447 void ParentNode::WalkDescendant(NodeOp& nodeOp)
448 {
449 Node* child = firstChild;
450 while (child != nullptr)
451 {
452 child->WalkDescendantOrSelf(nodeOp);
453 child = child->NextSibling();
454 }
455 }
456
457 void ParentNode::WalkDescendantOrSelf(NodeOp& nodeOp)
458 {
459 Node::WalkDescendantOrSelf(nodeOp);
460 Node* child = firstChild;
461 while (child != nullptr)
462 {
463 child->WalkDescendantOrSelf(nodeOp);
464 child = child->NextSibling();
465 }
466 }
467
468 void ParentNode::WalkPrecedingOrSelf(NodeOp& nodeOp)
469 {
470 Node::WalkPrecedingOrSelf(nodeOp);
471 Node* child = lastChild;
472 while (child != nullptr)
473 {
474 child->WalkPrecedingOrSelf(nodeOp);
475 child = child->PreviousSibling();
476 }
477 }
478
479 void ParentNode::WalkPreceding(NodeOp& nodeOp)
480 {
481 Node* preceding = PreviousSibling();
482 if (preceding)
483 {
484 preceding->WalkPrecedingOrSelf(nodeOp);
485 }
486 }
487
488 void NodeList::InternalAddNode(Node* node)
489 {
490 if (std::find(nodes.begin(), nodes.end(), node) == nodes.end())
491 {
492 nodes.push_back(node);
493 }
494 }
495
496 } }