1 | // |
---|
2 | // SAXParser.cpp |
---|
3 | // |
---|
4 | // $Id: //poco/1.3/XML/src/SAXParser.cpp#3 $ |
---|
5 | // |
---|
6 | // Library: XML |
---|
7 | // Package: SAX |
---|
8 | // Module: SAX |
---|
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/SAX/SAXParser.h> |
---|
38 | #include <Poco/SAX/SAXException.h> |
---|
39 | #include <Poco/SAX/EntityResolverImpl.h> |
---|
40 | #include <Poco/SAX/InputSource.h> |
---|
41 | #include <Poco/XML/NamespaceStrategy.h> |
---|
42 | #include <sstream> |
---|
43 | |
---|
44 | |
---|
45 | namespace Poco { |
---|
46 | namespace XML { |
---|
47 | |
---|
48 | |
---|
49 | const XMLString SAXParser::FEATURE_PARTIAL_READS = toXMLString("http://www.appinf.com/features/enable-partial-reads"); |
---|
50 | |
---|
51 | |
---|
52 | SAXParser::SAXParser(): |
---|
53 | _namespaces(true), |
---|
54 | _namespacePrefixes(false) |
---|
55 | { |
---|
56 | } |
---|
57 | |
---|
58 | |
---|
59 | SAXParser::SAXParser(const XMLString& encoding): |
---|
60 | _engine(encoding), |
---|
61 | _namespaces(true), |
---|
62 | _namespacePrefixes(false) |
---|
63 | { |
---|
64 | } |
---|
65 | |
---|
66 | |
---|
67 | SAXParser::~SAXParser() |
---|
68 | { |
---|
69 | } |
---|
70 | |
---|
71 | |
---|
72 | void SAXParser::setEncoding(const XMLString& encoding) |
---|
73 | { |
---|
74 | _engine.setEncoding(encoding); |
---|
75 | } |
---|
76 | |
---|
77 | |
---|
78 | const XMLString& SAXParser::getEncoding() const |
---|
79 | { |
---|
80 | return _engine.getEncoding(); |
---|
81 | } |
---|
82 | |
---|
83 | |
---|
84 | void SAXParser::addEncoding(const XMLString& name, Poco::TextEncoding* pEncoding) |
---|
85 | { |
---|
86 | _engine.addEncoding(name, pEncoding); |
---|
87 | } |
---|
88 | |
---|
89 | |
---|
90 | void SAXParser::setEntityResolver(EntityResolver* pResolver) |
---|
91 | { |
---|
92 | _engine.setEntityResolver(pResolver); |
---|
93 | } |
---|
94 | |
---|
95 | |
---|
96 | EntityResolver* SAXParser::getEntityResolver() const |
---|
97 | { |
---|
98 | return _engine.getEntityResolver(); |
---|
99 | } |
---|
100 | |
---|
101 | |
---|
102 | void SAXParser::setDTDHandler(DTDHandler* pDTDHandler) |
---|
103 | { |
---|
104 | _engine.setDTDHandler(pDTDHandler); |
---|
105 | } |
---|
106 | |
---|
107 | |
---|
108 | DTDHandler* SAXParser::getDTDHandler() const |
---|
109 | { |
---|
110 | return _engine.getDTDHandler(); |
---|
111 | } |
---|
112 | |
---|
113 | |
---|
114 | void SAXParser::setContentHandler(ContentHandler* pContentHandler) |
---|
115 | { |
---|
116 | _engine.setContentHandler(pContentHandler); |
---|
117 | } |
---|
118 | |
---|
119 | |
---|
120 | ContentHandler* SAXParser::getContentHandler() const |
---|
121 | { |
---|
122 | return _engine.getContentHandler(); |
---|
123 | } |
---|
124 | |
---|
125 | |
---|
126 | void SAXParser::setErrorHandler(ErrorHandler* pErrorHandler) |
---|
127 | { |
---|
128 | _engine.setErrorHandler(pErrorHandler); |
---|
129 | } |
---|
130 | |
---|
131 | |
---|
132 | ErrorHandler* SAXParser::getErrorHandler() const |
---|
133 | { |
---|
134 | return _engine.getErrorHandler(); |
---|
135 | } |
---|
136 | |
---|
137 | |
---|
138 | void SAXParser::setFeature(const XMLString& featureId, bool state) |
---|
139 | { |
---|
140 | if (featureId == XMLReader::FEATURE_VALIDATION || featureId == XMLReader::FEATURE_STRING_INTERNING) |
---|
141 | throw SAXNotSupportedException(fromXMLString(XMLReader::FEATURE_VALIDATION)); |
---|
142 | else if (featureId == XMLReader::FEATURE_EXTERNAL_GENERAL_ENTITIES) |
---|
143 | _engine.setExternalGeneralEntities(state); |
---|
144 | else if (featureId == XMLReader::FEATURE_EXTERNAL_PARAMETER_ENTITIES) |
---|
145 | _engine.setExternalParameterEntities(state); |
---|
146 | else if (featureId == XMLReader::FEATURE_NAMESPACES) |
---|
147 | _namespaces = state; |
---|
148 | else if (featureId == XMLReader::FEATURE_NAMESPACE_PREFIXES) |
---|
149 | _namespacePrefixes = state; |
---|
150 | else if (featureId == FEATURE_PARTIAL_READS) |
---|
151 | _engine.setEnablePartialReads(state); |
---|
152 | else throw SAXNotRecognizedException(fromXMLString(featureId)); |
---|
153 | } |
---|
154 | |
---|
155 | |
---|
156 | bool SAXParser::getFeature(const XMLString& featureId) const |
---|
157 | { |
---|
158 | if (featureId == XMLReader::FEATURE_VALIDATION || featureId == XMLReader::FEATURE_STRING_INTERNING) |
---|
159 | throw SAXNotSupportedException(fromXMLString(XMLReader::FEATURE_VALIDATION)); |
---|
160 | else if (featureId == XMLReader::FEATURE_EXTERNAL_GENERAL_ENTITIES) |
---|
161 | return _engine.getExternalGeneralEntities(); |
---|
162 | else if (featureId == XMLReader::FEATURE_EXTERNAL_PARAMETER_ENTITIES) |
---|
163 | return _engine.getExternalParameterEntities(); |
---|
164 | else if (featureId == XMLReader::FEATURE_NAMESPACES) |
---|
165 | return _namespaces; |
---|
166 | else if (featureId == XMLReader::FEATURE_NAMESPACE_PREFIXES) |
---|
167 | return _namespacePrefixes; |
---|
168 | else if (featureId == FEATURE_PARTIAL_READS) |
---|
169 | return _engine.getEnablePartialReads(); |
---|
170 | else throw SAXNotRecognizedException(fromXMLString(featureId)); |
---|
171 | } |
---|
172 | |
---|
173 | |
---|
174 | void SAXParser::setProperty(const XMLString& propertyId, const XMLString& value) |
---|
175 | { |
---|
176 | if (propertyId == XMLReader::PROPERTY_DECLARATION_HANDLER || propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) |
---|
177 | throw SAXNotSupportedException(std::string("property does not take a string value: ") + fromXMLString(propertyId)); |
---|
178 | else |
---|
179 | throw SAXNotRecognizedException(fromXMLString(propertyId)); |
---|
180 | } |
---|
181 | |
---|
182 | |
---|
183 | void SAXParser::setProperty(const XMLString& propertyId, void* value) |
---|
184 | { |
---|
185 | if (propertyId == XMLReader::PROPERTY_DECLARATION_HANDLER) |
---|
186 | _engine.setDeclHandler(reinterpret_cast<DeclHandler*>(value)); |
---|
187 | else if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) |
---|
188 | _engine.setLexicalHandler(reinterpret_cast<LexicalHandler*>(value)); |
---|
189 | else throw SAXNotRecognizedException(fromXMLString(propertyId)); |
---|
190 | } |
---|
191 | |
---|
192 | |
---|
193 | void* SAXParser::getProperty(const XMLString& propertyId) const |
---|
194 | { |
---|
195 | if (propertyId == XMLReader::PROPERTY_DECLARATION_HANDLER) |
---|
196 | return _engine.getDeclHandler(); |
---|
197 | else if (propertyId == XMLReader::PROPERTY_LEXICAL_HANDLER) |
---|
198 | return _engine.getLexicalHandler(); |
---|
199 | else throw SAXNotSupportedException(fromXMLString(propertyId)); |
---|
200 | } |
---|
201 | |
---|
202 | |
---|
203 | void SAXParser::parse(InputSource* pInputSource) |
---|
204 | { |
---|
205 | if (pInputSource->getByteStream() || pInputSource->getCharacterStream()) |
---|
206 | { |
---|
207 | setupParse(); |
---|
208 | _engine.parse(pInputSource); |
---|
209 | } |
---|
210 | else parse(pInputSource->getSystemId()); |
---|
211 | } |
---|
212 | |
---|
213 | |
---|
214 | void SAXParser::parse(const XMLString& systemId) |
---|
215 | { |
---|
216 | setupParse(); |
---|
217 | EntityResolverImpl entityResolver; |
---|
218 | InputSource* pInputSource = entityResolver.resolveEntity(0, systemId); |
---|
219 | if (pInputSource) |
---|
220 | { |
---|
221 | try |
---|
222 | { |
---|
223 | _engine.parse(pInputSource); |
---|
224 | } |
---|
225 | catch (...) |
---|
226 | { |
---|
227 | entityResolver.releaseInputSource(pInputSource); |
---|
228 | throw; |
---|
229 | } |
---|
230 | entityResolver.releaseInputSource(pInputSource); |
---|
231 | } |
---|
232 | else throw XMLException("Cannot resolve system identifier", fromXMLString(systemId)); |
---|
233 | } |
---|
234 | |
---|
235 | |
---|
236 | void SAXParser::parseString(const std::string& xml) |
---|
237 | { |
---|
238 | parseMemoryNP(xml.data(), xml.size()); |
---|
239 | } |
---|
240 | |
---|
241 | |
---|
242 | void SAXParser::parseMemoryNP(const char* xml, std::size_t size) |
---|
243 | { |
---|
244 | setupParse(); |
---|
245 | _engine.parse(xml, size); |
---|
246 | } |
---|
247 | |
---|
248 | |
---|
249 | void SAXParser::setupParse() |
---|
250 | { |
---|
251 | if (_namespaces && !_namespacePrefixes) |
---|
252 | _engine.setNamespaceStrategy(new NoNamespacePrefixesStrategy); |
---|
253 | else if (_namespaces && _namespacePrefixes) |
---|
254 | _engine.setNamespaceStrategy(new NamespacePrefixesStrategy); |
---|
255 | else |
---|
256 | _engine.setNamespaceStrategy(new NoNamespacesStrategy); |
---|
257 | } |
---|
258 | |
---|
259 | |
---|
260 | } } // namespace Poco::XML |
---|