source: XMLIO_V2/external/src/POCO/XML/Element.cpp @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

  • Property svn:eol-style set to native
File size: 10.9 KB
Line 
1//
2// Element.cpp
3//
4// $Id: //poco/1.3/XML/src/Element.cpp#2 $
5//
6// Library: XML
7// Package: DOM
8// Module:  DOM
9//
10// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// Permission is hereby granted, free of charge, to any person or organization
14// obtaining a copy of the software and accompanying documentation covered by
15// this license (the "Software") to use, reproduce, display, distribute,
16// execute, and transmit the Software, and to prepare derivative works of the
17// Software, and to permit third-parties to whom the Software is furnished to
18// do so, all subject to the following:
19//
20// The copyright notices in the Software and this entire statement, including
21// the above license grant, this restriction and the following disclaimer,
22// must be included in all copies of the Software, in whole or in part, and
23// all derivative works of the Software, unless such copies or derivative
24// works are solely in the form of machine-executable object code generated by
25// a source language processor.
26//
27// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
30// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
31// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
32// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33// DEALINGS IN THE SOFTWARE.
34//
35
36
37#include <Poco/DOM/Element.h>
38#include <Poco/DOM/Document.h>
39#include <Poco/DOM/Attr.h>
40#include <Poco/DOM/DOMException.h>
41#include <Poco/DOM/ElementsByTagNameList.h>
42#include <Poco/DOM/Text.h>
43#include <Poco/DOM/AttrMap.h>
44
45
46namespace Poco {
47namespace XML {
48
49
50Element::Element(Document* pOwnerDocument, const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname):
51        AbstractContainerNode(pOwnerDocument),
52        _name(pOwnerDocument->namePool().insert(qname, namespaceURI, localName)),
53        _pFirstAttr(0)
54{
55}
56
57
58Element::Element(Document* pOwnerDocument, const Element& element): 
59        AbstractContainerNode(pOwnerDocument, element),
60        _name(pOwnerDocument->namePool().insert(element._name)),
61        _pFirstAttr(0)
62{
63        Attr* pAttr = element._pFirstAttr;
64        while (pAttr)
65        {
66                Attr* pClonedAttr = static_cast<Attr*>(pAttr->copyNode(false, pOwnerDocument));
67                setAttributeNode(pClonedAttr);
68                pClonedAttr->release();
69                pAttr = static_cast<Attr*>(pAttr->_pNext);
70        }
71}
72
73
74Element::~Element()
75{
76        if (_pFirstAttr) _pFirstAttr->release();
77}
78
79
80const XMLString& Element::getAttribute(const XMLString& name) const
81{
82        Attr* pAttr = getAttributeNode(name);
83        if (pAttr)
84                return pAttr->getValue();
85        else
86                return EMPTY_STRING;
87}
88
89
90void Element::setAttribute(const XMLString& name, const XMLString& value)
91{
92        Attr* pAttr = getAttributeNode(name);
93        if (pAttr)
94        {
95                pAttr->setValue(value);
96        }
97        else
98        {
99                pAttr = ownerDocument()->createAttribute(name);
100                pAttr->setValue(value);
101                setAttributeNode(pAttr);
102                pAttr->release();
103        }
104}
105
106
107void Element::removeAttribute(const XMLString& name)
108{
109        Attr* pAttr = getAttributeNode(name);
110        if (pAttr) removeAttributeNode(pAttr);
111}
112
113
114Attr* Element::getAttributeNode(const XMLString& name) const
115{
116        Attr* pAttr = _pFirstAttr;
117        while (pAttr && pAttr->_name.qname() != name) pAttr = static_cast<Attr*>(pAttr->_pNext);
118        return pAttr;
119}
120
121
122Attr* Element::setAttributeNode(Attr* newAttr)
123{
124        poco_check_ptr (newAttr);
125
126        if (newAttr->ownerDocument() != ownerDocument())
127                throw DOMException(DOMException::WRONG_DOCUMENT_ERR);
128        if (newAttr->ownerElement())
129                throw DOMException(DOMException::INUSE_ATTRIBUTE_ERR);
130
131        Attr* oldAttr = getAttributeNode(newAttr->name());
132        if (oldAttr) removeAttributeNode(oldAttr);
133
134        Attr* pCur = _pFirstAttr;
135        if (pCur)
136        {
137                while (pCur->_pNext) pCur = static_cast<Attr*>(pCur->_pNext);
138                pCur->_pNext = newAttr;
139        }
140        else _pFirstAttr = newAttr;
141        newAttr->duplicate();
142        newAttr->_pParent = this;
143        if (_pOwner->events())
144                dispatchAttrModified(newAttr, MutationEvent::ADDITION, EMPTY_STRING, newAttr->getValue());
145
146        return oldAttr;
147}
148
149
150Attr* Element::removeAttributeNode(Attr* oldAttr)
151{
152        poco_check_ptr (oldAttr);
153
154        if (_pOwner->events()) 
155                dispatchAttrModified(oldAttr, MutationEvent::REMOVAL, oldAttr->getValue(), EMPTY_STRING);
156
157        if (oldAttr != _pFirstAttr)
158        {
159                Attr* pCur = _pFirstAttr;
160                while (pCur->_pNext != oldAttr) pCur = static_cast<Attr*>(pCur->_pNext);
161                if (pCur)
162                {
163                        pCur->_pNext = static_cast<Attr*>(pCur->_pNext->_pNext);
164                }
165                else throw DOMException(DOMException::NOT_FOUND_ERR);
166        }
167        else _pFirstAttr = static_cast<Attr*>(_pFirstAttr->_pNext);
168        oldAttr->_pNext   = 0;
169        oldAttr->_pParent = 0;
170        oldAttr->autoRelease();
171
172        return oldAttr;
173}
174
175
176Attr* Element::addAttributeNodeNP(Attr* oldAttr, Attr* newAttr)
177{
178        newAttr->_pParent = this;
179        if (oldAttr)
180        {
181                oldAttr->_pNext = newAttr;
182        }
183        else if (_pFirstAttr)
184        {
185                newAttr->_pNext = _pFirstAttr;
186                _pFirstAttr = newAttr;
187        }
188        else
189        {
190                _pFirstAttr = newAttr;
191        }
192        newAttr->duplicate();
193        return newAttr;
194}
195
196
197NodeList* Element::getElementsByTagName(const XMLString& name) const
198{
199        return new ElementsByTagNameList(this, name);
200}
201
202
203NodeList* Element::getElementsByTagNameNS(const XMLString& namespaceURI, const XMLString& localName) const
204{
205        return new ElementsByTagNameListNS(this, namespaceURI, localName);
206}
207
208
209void Element::normalize()
210{
211        Node* pCur = firstChild();
212        while (pCur)
213        {
214                if (pCur->nodeType() == Node::ELEMENT_NODE)
215                {
216                        pCur->normalize();
217                }
218                else if (pCur->nodeType() == Node::TEXT_NODE)
219                {
220                        Node* pNext = pCur->nextSibling();
221                        while (pNext && pNext->nodeType() == Node::TEXT_NODE)
222                        {
223                                static_cast<Text*>(pCur)->appendData(pNext->nodeValue());
224                                removeChild(pNext);
225                                pNext = pCur->nextSibling();
226                        }
227                }
228                pCur = pCur->nextSibling();
229        }
230}
231
232
233const XMLString& Element::nodeName() const
234{
235        return tagName();
236}
237
238
239NamedNodeMap* Element::attributes() const
240{
241        return new AttrMap(const_cast<Element*>(this));
242}
243
244
245unsigned short Element::nodeType() const
246{
247        return Node::ELEMENT_NODE;
248}
249
250
251const XMLString& Element::getAttributeNS(const XMLString& namespaceURI, const XMLString& localName) const
252{
253        Attr* pAttr = getAttributeNodeNS(namespaceURI, localName);
254        if (pAttr)
255                return pAttr->getValue();
256        else
257                return EMPTY_STRING;
258}
259
260
261void Element::setAttributeNS(const XMLString& namespaceURI, const XMLString& qualifiedName, const XMLString& value)
262{
263        Attr* pAttr = getAttributeNodeNS(namespaceURI, qualifiedName);
264        if (pAttr)
265        {
266                pAttr->setValue(value);
267        }
268        else
269        {
270                pAttr = _pOwner->createAttributeNS(namespaceURI, qualifiedName);
271                pAttr->setValue(value);
272                setAttributeNodeNS(pAttr);
273                pAttr->release();
274        }
275}
276
277
278void Element::removeAttributeNS(const XMLString& namespaceURI, const XMLString& localName)
279{
280        Attr* pAttr = getAttributeNodeNS(namespaceURI, localName);
281        if (pAttr) removeAttributeNode(pAttr);
282}
283
284
285Attr* Element::getAttributeNodeNS(const XMLString& namespaceURI, const XMLString& localName) const
286{
287        Attr* pAttr = _pFirstAttr;
288        while (pAttr && (pAttr->_name.namespaceURI() != namespaceURI || pAttr->_name.localName() != localName)) pAttr = static_cast<Attr*>(pAttr->_pNext);
289        return pAttr;
290}
291
292
293Attr* Element::setAttributeNodeNS(Attr* newAttr)
294{
295        poco_check_ptr (newAttr);
296
297        if (newAttr->ownerDocument() != ownerDocument())
298                throw DOMException(DOMException::WRONG_DOCUMENT_ERR);
299        if (newAttr->ownerElement())
300                throw DOMException(DOMException::INUSE_ATTRIBUTE_ERR);
301
302        Attr* oldAttr = getAttributeNodeNS(newAttr->namespaceURI(), newAttr->localName());
303        if (oldAttr) removeAttributeNode(oldAttr);
304
305        Attr* pCur = _pFirstAttr;
306        if (pCur)
307        {
308                while (pCur->_pNext) pCur = static_cast<Attr*>(pCur->_pNext);
309                pCur->_pNext = newAttr;
310        }
311        else _pFirstAttr = newAttr;
312        newAttr->_pParent = this;
313        newAttr->duplicate();
314        if (_pOwner->events())
315                dispatchAttrModified(newAttr, MutationEvent::ADDITION, EMPTY_STRING, newAttr->getValue());
316
317        return oldAttr;
318}
319
320
321bool Element::hasAttribute(const XMLString& name) const
322{
323        return getAttributeNode(name) != 0;
324}
325
326
327bool Element::hasAttributeNS(const XMLString& namespaceURI, const XMLString& localName) const
328{
329        return getAttributeNodeNS(namespaceURI, localName) != 0;
330}
331
332
333const XMLString& Element::namespaceURI() const
334{
335        return _name.namespaceURI();
336}
337
338
339XMLString Element::prefix() const
340{
341        return _name.prefix();
342}
343
344
345const XMLString& Element::localName() const
346{
347        return _name.localName();
348}
349
350
351bool Element::hasAttributes() const
352{
353        return _pFirstAttr != 0;
354}
355
356
357XMLString Element::innerText() const
358{
359        XMLString result;
360        Node* pChild = firstChild();
361        while (pChild)
362        {
363                result.append(pChild->innerText());
364                pChild = pChild->nextSibling();
365        }
366        return result;
367}
368
369
370Element* Element::getChildElement(const XMLString& name) const
371{
372        Node* pNode = firstChild();
373        while (pNode && !(pNode->nodeType() == Node::ELEMENT_NODE && pNode->nodeName() == name))
374                pNode = pNode->nextSibling();
375        return static_cast<Element*>(pNode);
376}
377
378
379Element* Element::getChildElementNS(const XMLString& namespaceURI, const XMLString& localName) const
380{
381        Node* pNode = firstChild();
382        while (pNode && !(pNode->nodeType() == Node::ELEMENT_NODE && pNode->namespaceURI() == namespaceURI && pNode->localName() == localName))
383                pNode = pNode->nextSibling();
384        return static_cast<Element*>(pNode);
385}
386
387
388void Element::dispatchNodeRemovedFromDocument()
389{
390        AbstractContainerNode::dispatchNodeRemovedFromDocument();
391        Attr* pAttr = _pFirstAttr;
392        while (pAttr)
393        {
394                pAttr->dispatchNodeRemovedFromDocument();
395                pAttr = static_cast<Attr*>(pAttr->_pNext);
396        }
397}
398
399
400void Element::dispatchNodeInsertedIntoDocument()
401{
402        AbstractContainerNode::dispatchNodeInsertedIntoDocument();
403        Attr* pAttr = _pFirstAttr;
404        while (pAttr)
405        {
406                pAttr->dispatchNodeInsertedIntoDocument();
407                pAttr = static_cast<Attr*>(pAttr->_pNext);
408        }
409}
410
411
412Node* Element::copyNode(bool deep, Document* pOwnerDocument) const
413{
414        Element* pClone = new Element(pOwnerDocument, *this);
415        if (deep)
416        {
417                Node* pNode = firstChild();
418                while (pNode)
419                {
420                        pClone->appendChild(static_cast<AbstractNode*>(pNode)->copyNode(true, pOwnerDocument))->release();
421                        pNode = pNode->nextSibling();
422                }
423        }
424        return pClone;
425}
426
427
428Element* Element::getElementById(const XMLString& elementId, const XMLString& idAttribute) const
429{
430        if (getAttribute(idAttribute) == elementId)
431                return const_cast<Element*>(this);
432
433        Node* pNode = firstChild();
434        while (pNode)
435        {
436                if (pNode->nodeType() == Node::ELEMENT_NODE)
437                {
438                        Element* pResult = static_cast<Element*>(pNode)->getElementById(elementId, idAttribute);
439                        if (pResult) return pResult;
440                }
441                pNode = pNode->nextSibling();
442        }
443        return 0;
444}
445
446
447Element* Element::getElementByIdNS(const XMLString& elementId, const XMLString& idAttributeURI, const XMLString& idAttributeLocalName) const
448{
449        if (getAttributeNS(idAttributeURI, idAttributeLocalName) == elementId)
450                return const_cast<Element*>(this);
451
452        Node* pNode = firstChild();
453        while (pNode)
454        {
455                if (pNode->nodeType() == Node::ELEMENT_NODE)
456                {
457                        Element* pResult = static_cast<Element*>(pNode)->getElementByIdNS(elementId, idAttributeURI, idAttributeLocalName);
458                        if (pResult) return pResult;
459                }
460                pNode = pNode->nextSibling();
461        }
462        return 0;
463}
464
465
466} } // namespace Poco::XML
Note: See TracBrowser for help on using the repository browser.