~ubuntu-branches/ubuntu/gutsy/poco/gutsy

« back to all changes in this revision

Viewing changes to XML/src/DOMBuilder.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Krzysztof Burghardt
  • Date: 2007-04-27 18:33:48 UTC
  • Revision ID: james.westby@ubuntu.com-20070427183348-xgnpct0qd6a2ip34
Tags: upstream-1.2.9
ImportĀ upstreamĀ versionĀ 1.2.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// DOMBuilder.cpp
 
3
//
 
4
// $Id: //poco/1.2/XML/src/DOMBuilder.cpp#1 $
 
5
//
 
6
// Library: XML
 
7
// Package: DOM
 
8
// Module:  DOMBuilder
 
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/DOMBuilder.h"
 
38
#include "Poco/DOM/Document.h"
 
39
#include "Poco/DOM/DocumentType.h"
 
40
#include "Poco/DOM/CharacterData.h"
 
41
#include "Poco/DOM/Text.h"
 
42
#include "Poco/DOM/Comment.h"
 
43
#include "Poco/DOM/CDATASection.h"
 
44
#include "Poco/DOM/Element.h"
 
45
#include "Poco/DOM/Attr.h"
 
46
#include "Poco/DOM/Entity.h"
 
47
#include "Poco/DOM/EntityReference.h"
 
48
#include "Poco/DOM/Notation.h"
 
49
#include "Poco/DOM/ProcessingInstruction.h"
 
50
#include "Poco/DOM/AutoPtr.h"
 
51
#include "Poco/SAX/XMLReader.h"
 
52
#include "Poco/SAX/AttributesImpl.h"
 
53
 
 
54
 
 
55
namespace Poco {
 
56
namespace XML {
 
57
 
 
58
 
 
59
const XMLString DOMBuilder::EMPTY_STRING;
 
60
 
 
61
 
 
62
DOMBuilder::DOMBuilder(XMLReader& xmlReader, NamePool* pNamePool):
 
63
        _xmlReader(xmlReader),
 
64
        _pNamePool(pNamePool),
 
65
        _pDocument(0),
 
66
        _pParent(0),
 
67
        _pPrevious(0),
 
68
        _inCDATA(false),
 
69
        _namespaces(true)
 
70
{
 
71
        _xmlReader.setContentHandler(this);
 
72
        _xmlReader.setDTDHandler(this);
 
73
        _xmlReader.setProperty(XMLReader::PROPERTY_LEXICAL_HANDLER, static_cast<LexicalHandler*>(this));
 
74
 
 
75
        if (_pNamePool) _pNamePool->duplicate();
 
76
}
 
77
 
 
78
 
 
79
DOMBuilder::~DOMBuilder()
 
80
{
 
81
        if (_pNamePool) _pNamePool->release();
 
82
}
 
83
 
 
84
 
 
85
Document* DOMBuilder::parse(const XMLString& uri)
 
86
{
 
87
        setupParse();
 
88
        _pDocument->suspendEvents();
 
89
        try
 
90
        {
 
91
                _xmlReader.parse(uri);
 
92
        }
 
93
        catch (...)
 
94
        {
 
95
                _pDocument->release();
 
96
                _pDocument = 0;
 
97
                _pParent   = 0;
 
98
                _pPrevious = 0;
 
99
                throw;
 
100
        }
 
101
        _pDocument->resumeEvents();
 
102
        _pDocument->collectGarbage();
 
103
        return _pDocument;
 
104
}
 
105
 
 
106
 
 
107
Document* DOMBuilder::parse(InputSource* pInputSource)
 
108
{
 
109
        setupParse();
 
110
        _pDocument->suspendEvents();
 
111
        try
 
112
        {
 
113
                _xmlReader.parse(pInputSource);
 
114
        }
 
115
        catch (...)
 
116
        {
 
117
                _pDocument->release();
 
118
                _pDocument = 0;
 
119
                _pParent   = 0;
 
120
                _pPrevious = 0;
 
121
                throw;
 
122
        }
 
123
        _pDocument->resumeEvents();
 
124
        _pDocument->collectGarbage();
 
125
        return _pDocument;
 
126
}
 
127
 
 
128
 
 
129
void DOMBuilder::setupParse()
 
130
{
 
131
        _pDocument  = new Document(_pNamePool);
 
132
        _pParent    = _pDocument;
 
133
        _pPrevious  = 0;
 
134
        _inCDATA    = false;
 
135
        _namespaces = _xmlReader.getFeature(XMLReader::FEATURE_NAMESPACES);
 
136
}
 
137
 
 
138
 
 
139
inline void DOMBuilder::appendNode(AbstractNode* pNode)
 
140
{
 
141
        if (_pPrevious && _pPrevious != _pParent)
 
142
        {
 
143
                _pPrevious->_pNext = pNode;
 
144
                pNode->_pParent = _pParent;
 
145
                pNode->duplicate();
 
146
        }
 
147
        else _pParent->appendChild(pNode);
 
148
        _pPrevious = pNode;
 
149
}
 
150
 
 
151
 
 
152
void DOMBuilder::notationDecl(const XMLString& name, const XMLString* publicId, const XMLString* systemId)
 
153
{
 
154
        DocumentType* pDoctype = _pDocument->getDoctype();
 
155
        if (pDoctype)
 
156
        {
 
157
                AutoPtr<Notation> pNotation = _pDocument->createNotation(name, (publicId ? *publicId : EMPTY_STRING), (systemId ? *systemId : EMPTY_STRING));
 
158
                pDoctype->appendChild(pNotation);
 
159
        }
 
160
}
 
161
 
 
162
 
 
163
void DOMBuilder::unparsedEntityDecl(const XMLString& name, const XMLString* publicId, const XMLString& systemId, const XMLString& notationName)
 
164
{
 
165
        DocumentType* pDoctype = _pDocument->getDoctype();
 
166
        if (pDoctype)
 
167
        {
 
168
                AutoPtr<Entity> pEntity = _pDocument->createEntity(name, publicId ? *publicId : EMPTY_STRING, systemId, notationName);
 
169
                pDoctype->appendChild(pEntity);
 
170
        }
 
171
}
 
172
 
 
173
 
 
174
void DOMBuilder::setDocumentLocator(const Locator* loc)
 
175
{
 
176
}
 
177
 
 
178
 
 
179
void DOMBuilder::startDocument()
 
180
{
 
181
}
 
182
 
 
183
 
 
184
void DOMBuilder::endDocument()
 
185
{
 
186
}
 
187
 
 
188
 
 
189
void DOMBuilder::startElement(const XMLString& uri, const XMLString& localName, const XMLString& qname, const Attributes& attributes)
 
190
{
 
191
        AutoPtr<Element> pElem = _namespaces ? _pDocument->createElementNS(uri, qname.empty() ? localName : qname) : _pDocument->createElement(qname);
 
192
 
 
193
        const AttributesImpl& attrs = dynamic_cast<const AttributesImpl&>(attributes);
 
194
        for (AttributesImpl::iterator it = attrs.begin(); it != attrs.end(); ++it)
 
195
        {
 
196
                AutoPtr<Attr> pAttr = new Attr(_pDocument, 0, it->namespaceURI, it->localName, it->qname, it->value, it->specified);
 
197
                if (_namespaces) 
 
198
                        pElem->setAttributeNodeNS(pAttr);
 
199
                else
 
200
                        pElem->setAttributeNode(pAttr);
 
201
        }
 
202
        appendNode(pElem);
 
203
        _pParent = pElem;
 
204
}
 
205
 
 
206
 
 
207
void DOMBuilder::endElement(const XMLString& uri, const XMLString& localName, const XMLString& qname)
 
208
{
 
209
        _pPrevious = _pParent;
 
210
        _pParent   = static_cast<AbstractContainerNode*>(_pParent->parentNode());
 
211
}
 
212
 
 
213
 
 
214
void DOMBuilder::characters(const XMLChar ch[], int start, int length)
 
215
{
 
216
        if (_inCDATA)
 
217
        {
 
218
                if (_pPrevious && _pPrevious->nodeType() == Node::CDATA_SECTION_NODE)
 
219
                {
 
220
                        static_cast<CDATASection*>(_pPrevious)->appendData(XMLString(ch + start, length));
 
221
                }
 
222
                else
 
223
                {
 
224
                        AutoPtr<CDATASection> pCDATA = _pDocument->createCDATASection(XMLString(ch + start, length));
 
225
                        appendNode(pCDATA);
 
226
                }
 
227
        }
 
228
        else
 
229
        {
 
230
                if (_pPrevious && _pPrevious->nodeType() == Node::TEXT_NODE)
 
231
                {
 
232
                        static_cast<Text*>(_pPrevious)->appendData(XMLString(ch + start, length));
 
233
                }
 
234
                else
 
235
                {
 
236
                        AutoPtr<Text> pText = _pDocument->createTextNode(XMLString(ch + start, length));
 
237
                        appendNode(pText);
 
238
                }
 
239
        }
 
240
}
 
241
 
 
242
 
 
243
void DOMBuilder::ignorableWhitespace(const XMLChar ch[], int start, int length)
 
244
{
 
245
        characters(ch, start, length);
 
246
}
 
247
 
 
248
 
 
249
void DOMBuilder::processingInstruction(const XMLString& target, const XMLString& data)
 
250
{
 
251
        AutoPtr<ProcessingInstruction> pPI = _pDocument->createProcessingInstruction(target, data);
 
252
        appendNode(pPI);
 
253
}
 
254
 
 
255
 
 
256
void DOMBuilder::startPrefixMapping(const XMLString& prefix, const XMLString& uri)
 
257
{
 
258
}
 
259
 
 
260
 
 
261
void DOMBuilder::endPrefixMapping(const XMLString& prefix)
 
262
{
 
263
}
 
264
 
 
265
 
 
266
void DOMBuilder::skippedEntity(const XMLString& name)
 
267
{
 
268
        AutoPtr<EntityReference> pER = _pDocument->createEntityReference(name);
 
269
        appendNode(pER);
 
270
}
 
271
 
 
272
 
 
273
void DOMBuilder::startDTD(const XMLString& name, const XMLString& publicId, const XMLString& systemId)
 
274
{
 
275
        AutoPtr<DocumentType> pDoctype = new DocumentType(_pDocument, name, publicId, systemId);
 
276
        _pDocument->setDoctype(pDoctype);
 
277
}
 
278
 
 
279
 
 
280
void DOMBuilder::endDTD()
 
281
{
 
282
}
 
283
 
 
284
 
 
285
void DOMBuilder::startEntity(const XMLString& name)
 
286
{
 
287
}
 
288
 
 
289
 
 
290
void DOMBuilder::endEntity(const XMLString& name)
 
291
{
 
292
}
 
293
 
 
294
 
 
295
void DOMBuilder::startCDATA()
 
296
{
 
297
        _inCDATA = true;
 
298
}
 
299
 
 
300
 
 
301
void DOMBuilder::endCDATA()
 
302
{
 
303
        _inCDATA = false;
 
304
}
 
305
 
 
306
 
 
307
void DOMBuilder::comment(const XMLChar ch[], int start, int length)
 
308
{
 
309
        AutoPtr<Comment> pComment = _pDocument->createComment(XMLString(ch + start, length));
 
310
        appendNode(pComment);
 
311
}
 
312
 
 
313
 
 
314
} } // namespace Poco::XML