2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
20 * @brief Simple c++ interface for libxml2.
22 #include <dpl/assert.h>
23 #include <dpl/exception.h>
24 #include <dpl/log/log.h>
26 #include "SaxReader.h"
28 namespace ValidationCore {
29 SaxReader::SaxReader() :
34 SaxReader::~SaxReader()
41 void SaxReader::initialize(const std::string &filename,
43 ValidationType validate,
44 const std::string &schema)
46 Assert(m_reader == 0 && "Double initialization of SaxReader");
48 LogDebug("SaxReader opening file: " << filename);
51 * create a new xml text reader
53 m_reader = xmlNewTextReaderFilename(filename.c_str());
55 if (m_reader == NULL) {
57 * no such file, return
59 LogWarning("Error during opening file " << filename);
60 Throw(Exception::FileOpeningError);
62 if (validate == VALIDATION_XMLSCHEME &&
63 xmlTextReaderSchemaValidate(m_reader, schema.c_str())) {
65 * unable to turn on schema validation
67 LogError("Turn on Schema validation failed.");
68 ThrowMsg(Exception::ParserInternalError,
69 "Turn on Scheme validation failed!");
71 // Path to DTD schema is taken from xml file.
72 if (validate == VALIDATION_DTD &&
73 xmlTextReaderSetParserProp(m_reader, XML_PARSER_VALIDATE, 1)) {
75 * unable to turn on DTD validation
77 LogError("Turn on DTD validation failed!");
78 ThrowMsg(Exception::ParserInternalError,
79 "Turn on DTD validation failed!");
82 xmlTextReaderSetParserProp(m_reader, XML_PARSER_DEFAULTATTRS, 1)) {
84 * unable to turn on default arguments
86 LogError("Turn on default arguments failed");
87 ThrowMsg(Exception::ParserInternalError,
88 "Turn on Default Arguments failed!");
92 void SaxReader::deinitialize()
94 xmlFreeTextReader(m_reader);
98 bool SaxReader::next()
100 int res = xmlTextReaderRead(m_reader);
102 if (0 == xmlTextReaderIsValid(m_reader)) {
103 LogWarning("Throw exception file not valid!");
104 Throw(Exception::FileNotValid);
114 LogError("ParserInternalError");
115 Throw(Exception::ParserInternalError);
118 void SaxReader::next(const std::string &token)
120 xmlTextReaderRead(m_reader);
121 if (0 == xmlTextReaderIsValid(m_reader)) {
125 LogWarning("Throw exception file not valid!");
126 Throw(Exception::FileNotValid);
129 xmlChar *name = xmlTextReaderName(m_reader);
135 LogWarning("File not Valid");
136 Throw(Exception::FileNotValid);
139 if (token == reinterpret_cast<const char*>(name)) {
143 * we encountered wrong token
146 LogWarning("Wrong Token");
147 Throw(Exception::WrongToken);
151 bool SaxReader::isEmpty(void)
153 int ret = xmlTextReaderIsEmptyElement(m_reader);
155 LogError("Parser Internal Error");
156 Throw(Exception::ParserInternalErrorInEmptyQuery);
161 std::string SaxReader::attribute(const std::string &token,
162 ThrowType throwStatus)
165 xmlChar *attr = xmlTextReaderGetAttribute(m_reader, BAD_CAST(token.c_str()));
166 if ((NULL == attr) && (throwStatus == THROW_DISABLE)) {
168 * return empty string
170 //TODO why not DPL::Optional?
171 return std::string();
175 * error during read attribute
177 LogError("Error in reading attribute.");
178 Throw(Exception::ParserInternalErrorInReadingAttribute);
182 * cast it to val and return it
184 value = reinterpret_cast<const char *>(attr);
189 // KW std::string SaxReader::fullName(){
190 // KW std::string value;
191 // KW xmlChar *name = xmlTextReaderName(m_reader);
192 // KW if(NULL == name) {
193 // KW LogError("Error in reading name.");
194 // KW Throw(Exception::ErrorReadingName);
196 // KW value = reinterpret_cast<const char *>(name);
201 std::string SaxReader::name()
204 xmlChar *name = xmlTextReaderName(m_reader);
206 LogError("Error in reading name.");
207 Throw(Exception::ErrorReadingName);
209 value = reinterpret_cast<const char *>(name);
211 size_t pos = value.find_last_of(":");
212 if (pos != std::string::npos) {
213 value.erase(0, pos + 1);
218 std::string SaxReader::namespaceURI()
221 xmlChar *name = xmlTextReaderNamespaceUri(m_reader);
223 value = reinterpret_cast<const char *>(name);
229 std::string SaxReader::value()
235 xmlChar *text = xmlTextReaderValue(m_reader);
237 LogError("Error in reading value");
238 Throw(Exception::ErrorReadingValue);
240 value = reinterpret_cast<const char*>(text);
242 * free text and return the val
248 SaxReader::NodeType SaxReader::type()
250 xmlReaderTypes type =
251 static_cast<xmlReaderTypes>(xmlTextReaderNodeType(m_reader));
253 case XML_READER_TYPE_ELEMENT:
255 case XML_READER_TYPE_END_ELEMENT:
257 case XML_READER_TYPE_TEXT:
259 case XML_READER_TYPE_NONE:
260 case XML_READER_TYPE_ATTRIBUTE:
261 case XML_READER_TYPE_CDATA:
262 case XML_READER_TYPE_ENTITY_REFERENCE:
263 case XML_READER_TYPE_ENTITY:
264 case XML_READER_TYPE_PROCESSING_INSTRUCTION:
265 case XML_READER_TYPE_COMMENT:
266 case XML_READER_TYPE_DOCUMENT:
267 case XML_READER_TYPE_DOCUMENT_TYPE:
268 case XML_READER_TYPE_DOCUMENT_FRAGMENT:
269 case XML_READER_TYPE_NOTATION:
270 case XML_READER_TYPE_WHITESPACE:
271 case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
272 case XML_READER_TYPE_END_ENTITY:
273 case XML_READER_TYPE_XML_DECLARATION:
275 return NODE_UNSUPPORTED;
279 void SaxReader::dumpNode(std::string &buffer)
288 xmlBufferPtr buff = xmlBufferCreate();
290 xmlNodePtr node = xmlTextReaderExpand(m_reader);
294 * internal parser error
297 LogError("Parser Internal Error");
298 Throw(Exception::ParserInternalError);
302 * get a size and fill in a buffer
304 size = xmlNodeDump(buff, node->doc, node, 0, 0);
305 buffer.insert(0, reinterpret_cast<char*>(buff->content), size);
308 } // namespace ValidationCore