-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathxml_util.c
164 lines (138 loc) · 3.48 KB
/
xml_util.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include <apr.h>
#include <apr_strings.h>
#include <httpd.h>
#include <libxml/tree.h>
#include <libxml/entities.h>
#include <libxml/xmlmemory.h>
#include "private.h"
#include "buffer.h"
#include "db.h"
#include "req.h"
#include "xml_util.h"
/**
* xml_find_child: Find child with given tagname.
* @n: The parent node,
* @tag: The tagname.
*
* Finds the first child of @n with tagname @tag.
*
* Return value: the child found, or NULL if none found.
**/
xmlNode *
virgule_xml_find_child (xmlNode *n, const char *tag)
{
xmlNode *child;
if (n == NULL)
return NULL;
for (child = n->children; child != NULL; child = child->next)
if (!strcmp ((char *)child->name, tag))
return child;
return NULL;
}
/**
* xml_ensure_child: Find child with given tagname, create if needed.
* @n: The parent node,
* @tag: The tagname.
*
* Finds the first child of @n with tagname @tag. If the child does
* not exist, creates a new child.
*
* Return value: the child found.
**/
xmlNode *
virgule_xml_ensure_child (xmlNode *n, const char *tag)
{
xmlNode *child;
for (child = n->children; child != NULL; child = child->next)
if (!strcmp ((char *)child->name, tag))
return child;
return xmlNewChild (n, NULL, (xmlChar *)tag, NULL);
}
char *
virgule_xml_get_string_contents (xmlNode *n)
{
if(n == NULL)
return NULL;
xmlNode *child = n->children;
while (child && child->type != XML_TEXT_NODE && child->type != XML_CDATA_SECTION_NODE)
child = child->next;
if (child)
return (char *)child->content;
else
return NULL;
}
/**
* virgule_xml_get_all_string_contents - like Raph's original except
* all string and CDATA nodes are returned rather than just the first one.
**/
char *
virgule_xml_get_all_string_contents (apr_pool_t *p, xmlNode *n)
{
char *result = NULL;
if(n == NULL || n->children == NULL)
return NULL;
xmlNode *child = n->children;
while (child)
{
if (child->content && (child->type == XML_TEXT_NODE || child->type == XML_CDATA_SECTION_NODE))
result = result ? apr_pstrcat (p, result, (char *)child->content, NULL)
: apr_pstrdup (p, (char *)child->content);
child = child->next;
}
return result;
}
/**
* virgule_xml_del_string_contents - remove any text or CDATA child nodes
* while leaving other nodes intact.
**/
void
virgule_xml_del_string_contents (xmlNode *n)
{
xmlNode *child = n->children;
xmlNode *tmp;
while (child)
{
if(child->type == XML_TEXT_NODE || child->type == XML_CDATA_SECTION_NODE)
{
tmp = child;
child = tmp->next;
xmlUnlinkNode(tmp);
xmlFreeNode(tmp);
}
else
child = child->next;
}
}
/* xmlGetProp with Apache-friendly allocation */
char *
virgule_xml_get_prop (apr_pool_t *p, xmlNodePtr node, const xmlChar *name)
{
char *value;
char *result;
value = (char *)xmlGetProp (node, name);
if (value == NULL)
return NULL;
result = apr_pstrdup (p, value);
xmlFree (value);
return result;
}
/**
* xml_find_child_string: Find child with given tagname, in string form.
* @n: The parent node.
* @tag: The tagname.
* @def: A default string.
*
* Finds the first child of @n with tagname @tag, extracting a string.
*
* Return value: the string, or @def if not found.
**/
char *
virgule_xml_find_child_string (xmlNode *n, const char *tag, char *def)
{
xmlNode *child;
child = virgule_xml_find_child (n, tag);
if (child == NULL)
return def;
else
return virgule_xml_get_string_contents (child);
}