1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 /* Copyright (C) 2001-2004 Novell, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU Lesser General Public
7 * License as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
24 #include "e2k-xml-utils.h"
26 #include <libxml/HTMLparser.h>
27 #include <libxml/parserInternals.h>
28 #include <libxml/xmlmemory.h>
31 my_xml_parser_error_handler (void *ctx, const char *msg, ...)
38 * @buf: the data to parse
39 * @len: the length of the buffer, or -1 if it is '\0'-terminated
41 * Parses the XML document in @buf.
43 * Return value: a pointer to an #xmlDoc
46 e2k_parse_xml (const char *buf, int len)
48 static xmlSAXHandler *sax;
49 xmlParserCtxtPtr ctxt;
52 g_return_val_if_fail (buf != NULL, NULL);
56 sax = xmlMalloc (sizeof (xmlSAXHandler));
57 #if LIBXML_VERSION > 20600
58 xmlSAXVersion (sax, 2);
60 memcpy (sax, &xmlDefaultSAXHandler, sizeof (xmlSAXHandler));
62 sax->warning = my_xml_parser_error_handler;
63 sax->error = my_xml_parser_error_handler;
68 ctxt = xmlCreateMemoryParserCtxt (buf, len);
74 #if LIBXML_VERSION > 20600
76 ctxt->str_xml = xmlDictLookup (ctxt->dict, BAD_CAST "xml", 3);
77 ctxt->str_xmlns = xmlDictLookup (ctxt->dict, BAD_CAST "xmlns", 5);
78 ctxt->str_xml_ns = xmlDictLookup (ctxt->dict, XML_XML_NAMESPACE, 36);
81 /* We set recover to TRUE because Exchange will let you
82 * put control-characters into data, which will make the
83 * XML be not well-formed.
85 ctxt->recovery = TRUE;
86 ctxt->vctxt.error = my_xml_parser_error_handler;
87 ctxt->vctxt.warning = my_xml_parser_error_handler;
89 xmlParseDocument (ctxt);
93 xmlFreeParserCtxt (ctxt);
100 * @buf: the data to parse
101 * @len: the length of the buffer, or -1 if it is '\0'-terminated
103 * Parses the HTML document in @buf.
105 * Return value: a pointer to an #xmlDoc
108 e2k_parse_html (const char *buf, int len)
111 #if LIBXML_VERSION > 20600
112 static xmlSAXHandler *sax;
113 htmlParserCtxtPtr ctxt;
115 g_return_val_if_fail (buf != NULL, NULL);
119 sax = xmlMalloc (sizeof (htmlSAXHandler));
120 memcpy (sax, &htmlDefaultSAXHandler, sizeof (xmlSAXHandlerV1));
121 sax->warning = my_xml_parser_error_handler;
122 sax->error = my_xml_parser_error_handler;
127 ctxt = htmlCreateMemoryParserCtxt (buf, len);
133 ctxt->vctxt.error = my_xml_parser_error_handler;
134 ctxt->vctxt.warning = my_xml_parser_error_handler;
136 htmlParseDocument (ctxt);
140 htmlFreeParserCtxt (ctxt);
142 #else /* LIBXML_VERSION <= 20600 */
143 char *buf_copy = g_strndup (buf, len);
145 doc = htmlParseDoc (buf_copy, NULL);
153 * e2k_g_string_append_xml_escaped:
154 * @string: a %GString containing XML data
155 * @value: data to append to @string
157 * Appends @value to @string, escaping any characters that can't appear
158 * unencoded in XML text (eg, "<").
161 e2k_g_string_append_xml_escaped (GString *string, const char *value)
166 g_string_append (string, "<");
169 g_string_append (string, ">");
172 g_string_append (string, "&");
175 g_string_append (string, """);
179 g_string_append_c (string, *value);
188 * @node: a node of an xml document
189 * @name: the name of the element to find
191 * Starts or continues a pre-order depth-first search of an xml
192 * document for an element named @name. @node is used as the starting
193 * point of the search, but is not examined itself.
195 * To search the complete document, pass the root node of the document
196 * as @node on the first call, and then on each successive call,
197 * pass the previous match as @node.
199 * Return value: the first matching element after @node, or %NULL when
200 * there are no more matches.
203 e2k_xml_find (xmlNode *node, const char *name)
205 return e2k_xml_find_in (node, NULL, name);
210 * @node: a node of an xml document
211 * @top: top of the search space
212 * @name: the name of the element to find
214 * Starts or continues a pre-order depth-first search of a subset of
215 * an xml document for an element named @name. @node is used as the
216 * starting point of the search, but is not examined itself. @top is
217 * the upper-most node that will be examined.
219 * To search the complete tree under a given node, pass that node as
220 * both @node and @top on the first call, and then on each successive
221 * call, pass the previous match as @node (with the original node
224 * Return value: the first matching element after @node, or %NULL when
225 * there are no more matches.
228 e2k_xml_find_in (xmlNode *node, xmlNode *top, const char *name)
230 g_return_val_if_fail (name != NULL, NULL);
233 /* If the current node has children, then the first
234 * child is the next node to examine. If it doesn't
235 * have children but does have a younger sibling, then
236 * that sibling is next up. Otherwise, climb back up
237 * the tree until we find a node that does have a
241 node = node->children;
243 while (node && !node->next && node != top)
245 if (!node || node == top)
250 if (node->name && !strcmp (node->name, name))