1 : /******************************************************************************
2 : * $Id: ili2handler.cpp 17910 2009-10-27 02:07:33Z chaitanya $
3 : *
4 : * Project: Interlis 2 Reader
5 : * Purpose: Implementation of ILI2Handler class.
6 : * Author: Markus Schnider, Sourcepole AG
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2004, Pirmin Kalberer, Sourcepole AG
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "ogr_ili2.h"
31 : #include "cpl_conv.h"
32 : #include "cpl_string.h"
33 :
34 : #include "ili2readerp.h"
35 : #include <xercesc/sax2/Attributes.hpp>
36 :
37 : CPL_CVSID("$Id: ili2handler.cpp 17910 2009-10-27 02:07:33Z chaitanya $");
38 :
39 : //
40 : // constants
41 : //
42 : static const char* ILI2_DATASECTION = "DATASECTION";
43 :
44 : //
45 : // ILI2Handler
46 : //
47 0 : ILI2Handler::ILI2Handler( ILI2Reader *poReader ) {
48 0 : m_poReader = poReader;
49 :
50 : // initialize once
51 : static int ili2DomTreeInitialized = FALSE;
52 :
53 0 : if (!ili2DomTreeInitialized) {
54 0 : XMLCh *tmpCh = XMLString::transcode("CORE");
55 0 : DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(tmpCh);
56 0 : XMLString::release(&tmpCh);
57 :
58 : // the root element
59 0 : tmpCh = XMLString::transcode("ROOT");
60 0 : dom_doc = impl->createDocument(0,tmpCh,0);
61 0 : XMLString::release(&tmpCh);
62 :
63 : // the first element is root
64 0 : dom_elem = dom_doc->getDocumentElement();
65 :
66 0 : ili2DomTreeInitialized = TRUE;
67 : }
68 0 : }
69 :
70 0 : ILI2Handler::~ILI2Handler() {
71 :
72 : // remove all elements
73 0 : DOMNode *tmpNode = dom_doc->getFirstChild();
74 0 : while (tmpNode != NULL) {
75 0 : tmpNode = dom_doc->removeChild(tmpNode);
76 0 : tmpNode = dom_doc->getFirstChild();
77 : }
78 :
79 : // release the dom tree
80 0 : dom_doc->release();
81 :
82 0 : }
83 :
84 :
85 0 : void ILI2Handler::startDocument() {
86 : // the level counter starts with DATASECTION
87 0 : level = -1;
88 0 : m_nEntityCounter = 0;
89 0 : }
90 :
91 0 : void ILI2Handler::endDocument() {
92 : // nothing to do
93 0 : }
94 :
95 0 : void ILI2Handler::startElement(
96 : const XMLCh* const uri,
97 : const XMLCh* const localname,
98 : const XMLCh* const qname,
99 : const Attributes& attrs
100 : ) {
101 :
102 : // start to add the layers, features with the DATASECTION
103 0 : char *tmpC = NULL;
104 0 : m_nEntityCounter = 0;
105 0 : if ((level >= 0) || (cmpStr(ILI2_DATASECTION, tmpC = XMLString::transcode(qname)) == 0)) {
106 0 : level++;
107 :
108 0 : if (level >= 2) {
109 :
110 : // create the dom tree
111 0 : DOMElement *elem = (DOMElement*)dom_doc->createElement(qname);
112 :
113 : // add all attributes
114 0 : unsigned int len = attrs.getLength();
115 0 : for (unsigned int index = 0; index < len; index++)
116 0 : elem->setAttribute(attrs.getQName(index), attrs.getValue(index));
117 0 : dom_elem->appendChild(elem);
118 0 : dom_elem = elem;
119 : }
120 : }
121 0 : XMLString::release(&tmpC);
122 0 : }
123 :
124 0 : void ILI2Handler::endElement(
125 : const XMLCh* const uri,
126 : const XMLCh* const localname,
127 : const XMLCh* const qname
128 : ) {
129 :
130 0 : m_nEntityCounter = 0;
131 0 : if (level >= 0) {
132 0 : if (level == 2) {
133 :
134 : // go to the parent element and parse the child element
135 0 : DOMElement* childElem = dom_elem;
136 0 : dom_elem = (DOMElement*)dom_elem->getParentNode();
137 :
138 0 : m_poReader->AddFeature(childElem);
139 :
140 : // remove the child element
141 0 : childElem = (DOMElement*)dom_elem->removeChild(childElem);
142 0 : } else if (level >= 3) {
143 :
144 : // go to the parent element
145 0 : dom_elem = (DOMElement*)dom_elem->getParentNode();
146 : }
147 0 : level--;
148 : }
149 0 : }
150 :
151 : #if XERCES_VERSION_MAJOR >= 3
152 : /************************************************************************/
153 : /* characters() (xerces 3 version) */
154 : /************************************************************************/
155 :
156 0 : void ILI2Handler::characters( const XMLCh *const chars,
157 : const XMLSize_t length ) {
158 :
159 : // add the text element
160 0 : if (level >= 3) {
161 0 : char *tmpC = XMLString::transcode(chars);
162 :
163 : // only add the text if it is not empty
164 0 : if (trim(tmpC) != "")
165 0 : dom_elem->appendChild(dom_doc->createTextNode(chars));
166 :
167 0 : XMLString::release(&tmpC);
168 : }
169 0 : }
170 :
171 : #else
172 : /************************************************************************/
173 : /* characters() (xerces 2 version) */
174 : /************************************************************************/
175 :
176 : void ILI2Handler::characters( const XMLCh *const chars,
177 : const unsigned int length ) {
178 :
179 : // add the text element
180 : if (level >= 3) {
181 : char *tmpC = XMLString::transcode(chars);
182 :
183 : // only add the text if it is not empty
184 : if (trim(tmpC) != "")
185 : dom_elem->appendChild(dom_doc->createTextNode(chars));
186 :
187 : XMLString::release(&tmpC);
188 : }
189 : }
190 : #endif
191 :
192 0 : void ILI2Handler::startEntity (const XMLCh *const name)
193 : {
194 0 : m_nEntityCounter ++;
195 0 : if (m_nEntityCounter > 1000)
196 : {
197 0 : throw SAXNotSupportedException ("File probably corrupted (million laugh pattern)");
198 : }
199 0 : }
200 :
201 0 : void ILI2Handler::fatalError(const SAXParseException&) {
202 : // FIXME Error handling
203 0 : }
|