1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xml_parser.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_shell.hxx"
34 #ifndef XML_PARSER_HXX_INCLUDED
35 #include "internal/xml_parser.hxx"
37 #include "internal/i_xml_parser_event_handler.hxx"
41 namespace /* private */
44 //######################################################
45 /* Extracts the local part of tag without
46 namespace decoration e.g. meta:creator -> creator */
47 const XML_Char COLON
= (XML_Char
)':';
49 const XML_Char
* get_local_name(const XML_Char
* rawname
)
51 const XML_Char
* p
= rawname
;
56 // go back until the first ':'
57 while (*p
!= COLON
&& p
> rawname
)
60 // if we are on a colon one step forward
67 //################################################
68 inline xml_parser
* get_parser_instance(void* data
)
70 return reinterpret_cast<xml_parser
*>(XML_GetUserData(
71 reinterpret_cast<XML_Parser
>(data
)));
74 //################################################
75 bool has_only_whitespaces(const XML_Char
* s
, int len
)
77 const XML_Char
* p
= s
;
78 for (int i
= 0; i
< len
; i
++)
79 if (*p
++ != ' ') return false;
84 //###################################################
85 xml_parser::xml_parser(const XML_Char
* EncodingName
) :
87 xml_parser_(XML_ParserCreate(EncodingName
))
92 //###################################################
93 xml_parser::xml_parser(const XML_Char
* EncodingName
, XML_Char
/*NamespaceSeparator*/) :
95 xml_parser_(XML_ParserCreate(EncodingName
))
100 //###################################################
101 xml_parser::~xml_parser()
103 XML_ParserFree(xml_parser_
);
106 //###################################################
107 /* Callback functions will be called by the parser on
110 //###################################################
114 static void xml_start_element_handler(void* UserData
, const XML_Char
* name
, const XML_Char
** atts
)
116 assert(UserData
!= NULL
);
118 xml_parser
* pImpl
= get_parser_instance(UserData
);
120 i_xml_parser_event_handler
* pDocHdl
= pImpl
->get_document_handler();
123 xml_tag_attribute_container_t attributes
;
129 attributes
[reinterpret_cast<const char_t
*>(get_local_name(atts
[i
]))] = reinterpret_cast<const char_t
*>(atts
[i
+1]);
130 i
+= 2; // skip to next pair
133 pDocHdl
->start_element(
134 reinterpret_cast<const char_t
*>(name
), reinterpret_cast<const char_t
*>(get_local_name(name
)), attributes
);
138 //###################################################
139 static void xml_end_element_handler(void* UserData
, const XML_Char
* name
)
143 xml_parser
* pImpl
= get_parser_instance(UserData
);
144 i_xml_parser_event_handler
* pDocHdl
= pImpl
->get_document_handler();
146 pDocHdl
->end_element(reinterpret_cast<const char_t
*>(name
), reinterpret_cast<const char_t
*>(get_local_name(name
)));
149 //###################################################
150 static void xml_character_data_handler(void* UserData
, const XML_Char
* s
, int len
)
154 xml_parser
* pImpl
= get_parser_instance(UserData
);
155 i_xml_parser_event_handler
* pDocHdl
= pImpl
->get_document_handler();
158 if (has_only_whitespaces(s
,len
))
159 pDocHdl
->ignore_whitespace(string_t(reinterpret_cast<const char_t
*>(s
), len
));
161 pDocHdl
->characters(string_t(reinterpret_cast<const char_t
*>(s
), len
));
165 //###################################################
166 static void xml_comment_handler(void* UserData
, const XML_Char
* Data
)
170 xml_parser
* pImpl
= get_parser_instance(UserData
);
171 i_xml_parser_event_handler
* pDocHdl
= pImpl
->get_document_handler();
173 pDocHdl
->comment(reinterpret_cast<const char_t
*>(Data
));
178 //###################################################
179 void xml_parser::init()
181 XML_SetUserData(xml_parser_
, this);
183 // we use the parser as handler argument,
184 // so we could use it if necessary, the
185 // UserData are usable anyway using
186 // XML_GetUserData(...)
187 XML_UseParserAsHandlerArg(xml_parser_
);
189 XML_SetElementHandler(
191 xml_start_element_handler
,
192 xml_end_element_handler
);
194 XML_SetCharacterDataHandler(
196 xml_character_data_handler
);
198 XML_SetCommentHandler(
200 xml_comment_handler
);
203 //###################################################
204 void xml_parser::parse(const char* XmlData
, size_t Length
, bool IsFinal
)
206 if (0 == XML_Parse(xml_parser_
, XmlData
, Length
, IsFinal
))
207 throw xml_parser_exception(
208 (char*)XML_ErrorString(XML_GetErrorCode(xml_parser_
)),
209 (int)XML_GetErrorCode(xml_parser_
),
210 XML_GetCurrentLineNumber(xml_parser_
),
211 XML_GetCurrentColumnNumber(xml_parser_
),
212 XML_GetCurrentByteIndex(xml_parser_
));
215 //###################################################
216 void xml_parser::set_document_handler(
217 i_xml_parser_event_handler
* event_handler
)
219 document_handler_
= event_handler
;
222 //###################################################
223 i_xml_parser_event_handler
* xml_parser::get_document_handler() const
225 return document_handler_
;
228 //###################################################
229 void xml_parser::set_encoding(const XML_Char
* Encoding
)
231 XML_SetEncoding(xml_parser_
, Encoding
);