1 : /******************************************************************************
2 : * $Id: ili2handler.cpp 24408 2012-05-11 21:31:45Z pka $
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 24408 2012-05-11 21:31:45Z pka $");
38 :
39 : //
40 : // constants
41 : //
42 : static const char* ILI2_DATASECTION = "DATASECTION";
43 :
44 : //
45 : // ILI2Handler
46 : //
47 2 : ILI2Handler::ILI2Handler( ILI2Reader *poReader ) {
48 2 : m_poReader = poReader;
49 :
50 2 : XMLCh *tmpCh = XMLString::transcode("CORE");
51 2 : DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(tmpCh);
52 2 : XMLString::release(&tmpCh);
53 :
54 : // the root element
55 2 : tmpCh = XMLString::transcode("ROOT");
56 2 : dom_doc = impl->createDocument(0,tmpCh,0);
57 2 : XMLString::release(&tmpCh);
58 :
59 : // the first element is root
60 2 : dom_elem = dom_doc->getDocumentElement();
61 :
62 2 : }
63 :
64 2 : ILI2Handler::~ILI2Handler() {
65 :
66 : // remove all elements
67 2 : DOMNode *tmpNode = dom_doc->getFirstChild();
68 6 : while (tmpNode != NULL) {
69 2 : tmpNode = dom_doc->removeChild(tmpNode);
70 2 : tmpNode = dom_doc->getFirstChild();
71 : }
72 :
73 : // release the dom tree
74 2 : dom_doc->release();
75 :
76 2 : }
77 :
78 :
79 2 : void ILI2Handler::startDocument() {
80 : // the level counter starts with DATASECTION
81 2 : level = -1;
82 2 : m_nEntityCounter = 0;
83 2 : }
84 :
85 2 : void ILI2Handler::endDocument() {
86 : // nothing to do
87 2 : }
88 :
89 1384 : void ILI2Handler::startElement(
90 : const XMLCh* const uri,
91 : const XMLCh* const localname,
92 : const XMLCh* const qname,
93 : const Attributes& attrs
94 : ) {
95 :
96 : // start to add the layers, features with the DATASECTION
97 1384 : char *tmpC = NULL;
98 1384 : m_nEntityCounter = 0;
99 1384 : if ((level >= 0) || (cmpStr(ILI2_DATASECTION, tmpC = XMLString::transcode(qname)) == 0)) {
100 1298 : level++;
101 :
102 1298 : if (level >= 2) {
103 :
104 : // create the dom tree
105 1294 : DOMElement *elem = (DOMElement*)dom_doc->createElement(qname);
106 :
107 : // add all attributes
108 1294 : unsigned int len = attrs.getLength();
109 1378 : for (unsigned int index = 0; index < len; index++)
110 84 : elem->setAttribute(attrs.getQName(index), attrs.getValue(index));
111 1294 : dom_elem->appendChild(elem);
112 1294 : dom_elem = elem;
113 : }
114 : }
115 1384 : XMLString::release(&tmpC);
116 1384 : }
117 :
118 1384 : void ILI2Handler::endElement(
119 : const XMLCh* const uri,
120 : const XMLCh* const localname,
121 : const XMLCh* const qname
122 : ) {
123 :
124 1384 : m_nEntityCounter = 0;
125 1384 : if (level >= 0) {
126 1298 : if (level == 2) {
127 :
128 : // go to the parent element and parse the child element
129 62 : DOMElement* childElem = dom_elem;
130 62 : dom_elem = (DOMElement*)dom_elem->getParentNode();
131 :
132 62 : m_poReader->AddFeature(childElem);
133 :
134 : // remove the child element
135 62 : childElem = (DOMElement*)dom_elem->removeChild(childElem);
136 1236 : } else if (level >= 3) {
137 :
138 : // go to the parent element
139 1232 : dom_elem = (DOMElement*)dom_elem->getParentNode();
140 : }
141 1298 : level--;
142 : }
143 1384 : }
144 :
145 : #if XERCES_VERSION_MAJOR >= 3
146 : /************************************************************************/
147 : /* characters() (xerces 3 version) */
148 : /************************************************************************/
149 :
150 : void ILI2Handler::characters( const XMLCh *const chars,
151 : const XMLSize_t length ) {
152 :
153 : // add the text element
154 : if (level >= 3) {
155 : char *tmpC = XMLString::transcode(chars);
156 :
157 : // only add the text if it is not empty
158 : if (trim(tmpC) != "")
159 : dom_elem->appendChild(dom_doc->createTextNode(chars));
160 :
161 : XMLString::release(&tmpC);
162 : }
163 : }
164 :
165 : #else
166 : /************************************************************************/
167 : /* characters() (xerces 2 version) */
168 : /************************************************************************/
169 :
170 1778 : void ILI2Handler::characters( const XMLCh *const chars,
171 : const unsigned int length ) {
172 :
173 : // add the text element
174 1778 : if (level >= 3) {
175 1398 : char *tmpC = XMLString::transcode(chars);
176 :
177 : // only add the text if it is not empty
178 1398 : if (trim(tmpC) != "")
179 696 : dom_elem->appendChild(dom_doc->createTextNode(chars));
180 :
181 1398 : XMLString::release(&tmpC);
182 : }
183 1778 : }
184 : #endif
185 :
186 0 : void ILI2Handler::startEntity (const XMLCh *const name)
187 : {
188 0 : m_nEntityCounter++;
189 0 : if (m_nEntityCounter > 1000)
190 : {
191 0 : throw SAXNotSupportedException ("File probably corrupted (million laugh pattern)");
192 : }
193 0 : }
194 :
195 0 : void ILI2Handler::fatalError(const SAXParseException&) {
196 : // FIXME Error handling
197 0 : }
|