+2006-11-06 Dan Winship <danw@novell.com>
+
+ * libsoup/soup-misc.c (soup_xml_real_node): new method to find a
+ "real" (ie, not comment or whitespace) xml node
+
+ * libsoup/soup-soap-response.c (parse_parameters)
+ (soup_soap_response_from_string)
+ (soup_soap_parameter_get_first_child)
+ (soup_soap_parameter_get_next_child): Use soup_xml_real_node.
+ Based on a patch from Andrew W. Nosenko.
+
+ * libsoup/soup-xmlrpc-message.c (soup_xmlrpc_message_from_string):
+ don't call xmlKeepBlanksDefault, which changes libxml's behavior
+ globally! Instead, use soup_xml_real_node() when traversing the
+ xml tree.
+
+ * libsoup/soup-xmlrpc-response.c
+ (soup_xmlrpc_response_from_string): don't call
+ xmlKeepBlanksDefault.
+ (exactly_one_child): rewrite in terms of soup_xml_real_node()
+ (which means it handles comments now as well)
+ (soup_xmlrpc_value_get_struct)
+ (soup_xmlrpc_value_array_get_iterator)
+ (soup_xmlrpc_value_array_iterator_prev)
+ (soup_xmlrpc_value_array_iterator_next): Use soup_xml_real_node.
+
2006-11-05 Dan Winship <danw@novell.com>
* libsoup/soup-headers.c (soup_headers_parse_request): document
return source;
}
+/**
+ * soup_xml_real_node:
+ * @node: an %xmlNodePtr
+ *
+ * Finds the first "real" node (ie, not a comment or whitespace) at or
+ * after @node at its level in the tree.
+ *
+ * Return: a node, or %NULL
+ **/
+xmlNode *
+soup_xml_real_node (xmlNode *node)
+{
+ while (node && (node->type == XML_COMMENT_NODE ||
+ xmlIsBlankNode (node)))
+ node = node->next;
+ return node;
+}
#define SOUP_MISC_H 1
#include <glib-object.h>
+#include <libxml/tree.h>
/* Base64 encoding/decoding */
gboolean soup_str_case_equal (gconstpointer v1,
gconstpointer v2);
+xmlNode *soup_xml_real_node (xmlNode *node);
+
/**
* soup_ssl_supported:
*
{
xmlNodePtr tmp;
- for (tmp = xml_method->xmlChildrenNode; tmp != NULL; tmp = tmp->next) {
+ for (tmp = soup_xml_real_node (xml_method->children);
+ tmp != NULL;
+ tmp = soup_xml_real_node (tmp->next)) {
if (!strcmp ((const char *)tmp->name, "Fault")) {
priv->soap_fault = tmp;
continue;
{
SoupSoapResponsePrivate *priv;
xmlDocPtr old_doc = NULL;
- xmlNodePtr xml_root, xml_body = NULL, xml_method = NULL;
+ xmlNodePtr xml_root, xml_body, xml_method = NULL;
g_return_val_if_fail (SOUP_IS_SOAP_RESPONSE (response), FALSE);
priv = SOUP_SOAP_RESPONSE_GET_PRIVATE (response);
return FALSE;
}
- if (xml_root->xmlChildrenNode != NULL) {
- xml_body = xml_root->xmlChildrenNode;
+ xml_body = soup_xml_real_node (xml_root->children);
+ if (xml_body != NULL) {
if (strcmp ((const char *)xml_body->name, "Header") == 0)
- xml_body = xml_root->xmlChildrenNode->next;
+ xml_body = soup_xml_real_node (xml_body->next);
if (strcmp ((const char *)xml_body->name, "Body") != 0) {
xmlFreeDoc (priv->xmldoc);
priv->xmldoc = old_doc;
return FALSE;
}
- xml_method = xml_body->xmlChildrenNode;
+ xml_method = soup_xml_real_node (xml_body->children);
/* read all parameters */
if (xml_method)
{
g_return_val_if_fail (param != NULL, NULL);
- return param->xmlChildrenNode ? param->xmlChildrenNode : NULL;
+ return soup_xml_real_node (param->children);
}
/**
{
g_return_val_if_fail (param != NULL, NULL);
- return param->next;
+ return soup_xml_real_node (param->next);
}
/**
{
SoupXmlrpcMessagePrivate *priv = SOUP_XMLRPC_MESSAGE_GET_PRIVATE (msg);
- xmlKeepBlanksDefault (0);
-
priv->doc = xmlNewDoc ((const xmlChar *)"1.0");
priv->doc->standalone = FALSE;
priv->doc->encoding = xmlCharStrdup ("UTF-8");
priv = SOUP_XMLRPC_MESSAGE_GET_PRIVATE (message);
g_return_val_if_fail (xmlstr != NULL, FALSE);
- xmlKeepBlanksDefault (0);
newdoc = xmlParseMemory (xmlstr, strlen (xmlstr));
if (!newdoc)
return FALSE;
if (!body || strcmp ((const char *)body->name, "methodCall"))
goto bad;
- body = body->children;
+ body = soup_xml_real_node (body->children);
if (!body || strcmp ((const char *)body->name, "methodName"))
goto bad;
- body = body->next;
+ body = soup_xml_real_node (body->next);
if (!body || strcmp ((const char *)body->name, "params"))
goto bad;
static xmlNode *
exactly_one_child (xmlNode *node)
{
- xmlNode *child, *tmp;
-
- tmp = node->children;
- while (tmp && xmlIsBlankNode (tmp))
- tmp = tmp->next;
-
- child = tmp;
- if (tmp && tmp->next) {
- tmp = tmp->next;
- while (tmp && xmlIsBlankNode (tmp))
- tmp = tmp->next;
- if (tmp)
- return NULL;
- }
+ xmlNode *child;
+
+ child = soup_xml_real_node (node->children);
+ if (!child || soup_xml_real_node (child->next))
+ return NULL;
return child;
}
priv = SOUP_XMLRPC_RESPONSE_GET_PRIVATE (response);
g_return_val_if_fail (xmlstr != NULL, FALSE);
- xmlKeepBlanksDefault (0);
newdoc = xmlParseMemory (xmlstr, strlen (xmlstr));
if (!newdoc)
goto very_bad;
t = g_hash_table_new_full (g_str_hash, g_str_equal, xmlFree, NULL);
- for (xml = xml->children; xml; xml = xml->next) {
+ for (xml = soup_xml_real_node (xml->children);
+ xml;
+ xml = soup_xml_real_node (xml->next)) {
xmlChar *name;
xmlNode *val, *cur;
- if (strcmp ((const char *)xml->name, "member") || !xml->children)
+ if (strcmp ((const char *)xml->name, "member") ||
+ !xml->children)
goto bad;
name = NULL;
val = NULL;
- for (cur = xml->children; cur; cur = cur->next) {
+ for (cur = soup_xml_real_node (xml->children);
+ cur;
+ cur = soup_xml_real_node (cur->next)) {
if (strcmp((const char *)cur->name, "name") == 0) {
if (name)
goto local_bad;
name = xmlNodeGetContent (cur);
- }
- else if (strcmp ((const char *)cur->name, "value") == 0)
+ } else if (strcmp ((const char *)cur->name, "value") == 0)
val = cur;
- else goto local_bad;
+ else
+ goto local_bad;
continue;
local_bad:
- if (name) xmlFree (name);
+ if (name)
+ xmlFree (name);
goto bad;
}
if (!name || !val) {
- if (name) xmlFree (name);
+ if (name)
+ xmlFree (name);
goto bad;
}
g_hash_table_insert (t, name, val);
gboolean
soup_xmlrpc_value_array_get_iterator (SoupXmlrpcValue *value, SoupXmlrpcValueArrayIterator **iter)
{
- xmlNode *xml;
+ xmlNode *xml, *array, *data;
xml = (xmlNode *) value;
- if (!xml->children || strcmp((const char *)xml->children->name, "array") != 0 ||
- xml->children->next || !xml->children->children ||
- strcmp((const char *)xml->children->children->name, "data") != 0 ||
- xml->children->children->next)
+ array = soup_xml_real_node (xml->children);
+ if (!array || strcmp((const char *)array->name, "array") != 0 ||
+ soup_xml_real_node (array->next))
+ return FALSE;
+
+ data = soup_xml_real_node (array->children);
+ if (!data || strcmp((const char *)data->name, "data") != 0 ||
+ soup_xml_real_node (data->next))
return FALSE;
- *iter = (SoupXmlrpcValueArrayIterator *) xml->children->children->children;
+ *iter = (SoupXmlrpcValueArrayIterator *) soup_xml_real_node (data->children);
return TRUE;
}
SoupXmlrpcValueArrayIterator *
soup_xmlrpc_value_array_iterator_prev (SoupXmlrpcValueArrayIterator *iter)
{
- xmlNode *xml;
+ xmlNode *xml, *prev;
xml = (xmlNode *) iter;
- return (SoupXmlrpcValueArrayIterator *) xml->prev;
+ prev = xml->prev;
+ while (prev != soup_xml_real_node (prev))
+ prev = prev->prev;
+
+ return (SoupXmlrpcValueArrayIterator *) prev;
}
SoupXmlrpcValueArrayIterator *
xml = (xmlNode *) iter;
- return (SoupXmlrpcValueArrayIterator *) xml->next;
+ return (SoupXmlrpcValueArrayIterator *) soup_xml_real_node (xml->next);
}
gboolean