summaryrefslogtreecommitdiff
path: root/xml/apr_xml.c
diff options
context:
space:
mode:
Diffstat (limited to 'xml/apr_xml.c')
-rw-r--r--xml/apr_xml.c91
1 files changed, 77 insertions, 14 deletions
diff --git a/xml/apr_xml.c b/xml/apr_xml.c
index b3ec875781e24..ec3bea7497617 100644
--- a/xml/apr_xml.c
+++ b/xml/apr_xml.c
@@ -86,7 +86,7 @@ static int find_prefix(apr_xml_parser *parser, const char *prefix)
** prefix.
*/
for (; elem; elem = elem->parent) {
- apr_xml_ns_scope *ns_scope = elem->ns_scope;
+ apr_xml_ns_scope *ns_scope;
for (ns_scope = elem->ns_scope; ns_scope; ns_scope = ns_scope->next) {
if (strcmp(prefix, ns_scope->prefix) == 0) {
@@ -120,6 +120,26 @@ static int find_prefix(apr_xml_parser *parser, const char *prefix)
return APR_XML_NS_ERROR_UNKNOWN_PREFIX;
}
+/* return original prefix given ns index */
+static const char * find_prefix_name(const apr_xml_elem *elem, int ns, int parent)
+{
+ /*
+ ** Walk up the tree, looking for a namespace scope that defines this
+ ** prefix.
+ */
+ for (; elem; elem = parent ? elem->parent : NULL) {
+ apr_xml_ns_scope *ns_scope = elem->ns_scope;
+
+ for (; ns_scope; ns_scope = ns_scope->next) {
+ if (ns_scope->ns == ns)
+ return ns_scope->prefix;
+ }
+ }
+ /* not found */
+ return "";
+}
+
+
static void start_handler(void *userdata, const char *name, const char **attrs)
{
apr_xml_parser *parser = userdata;
@@ -646,7 +666,8 @@ static apr_size_t elem_size(const apr_xml_elem *elem, int style,
{
apr_size_t size;
- if (style == APR_XML_X2T_FULL || style == APR_XML_X2T_FULL_NS_LANG) {
+ if (style == APR_XML_X2T_FULL || style == APR_XML_X2T_FULL_NS_LANG ||
+ style == APR_XML_X2T_PARSED) {
const apr_xml_attr *attr;
size = 0;
@@ -670,11 +691,29 @@ static apr_size_t elem_size(const apr_xml_elem *elem, int style,
size += 11 + strlen(elem->lang) + 1;
}
}
+ else if (style == APR_XML_X2T_PARSED) {
+ apr_xml_ns_scope *ns_scope = elem->ns_scope;
+
+ /* compute size of: ' xmlns:%s="%s"' */
+ for (; ns_scope; ns_scope = ns_scope->next) {
+ size += 10 + strlen(find_prefix_name(elem, ns_scope->ns, 0)) +
+ strlen(APR_XML_GET_URI_ITEM(namespaces, ns_scope->ns));
+ }
+
+ if (elem->lang != NULL) {
+ /* compute size of: ' xml:lang="%s"' */
+ size += 11 + strlen(elem->lang) + 1;
+ }
+ }
if (elem->ns == APR_XML_NS_NONE) {
/* compute size of: <%s> */
size += 1 + strlen(elem->name) + 1;
}
+ else if (style == APR_XML_X2T_PARSED) {
+ /* compute size of: <%s:%s> */
+ size += 3 + strlen(find_prefix_name(elem, elem->ns, 1)) + strlen(elem->name);
+ }
else {
int ns = ns_map ? ns_map[elem->ns] : elem->ns;
@@ -700,6 +739,10 @@ static apr_size_t elem_size(const apr_xml_elem *elem, int style,
/* compute size of: ' %s="%s"' */
size += 1 + strlen(attr->name) + 2 + strlen(attr->value) + 1;
}
+ else if (style == APR_XML_X2T_PARSED) {
+ /* compute size of: ' %s:%s="%s"' */
+ size += 5 + strlen(find_prefix_name(elem, attr->ns, 1)) + strlen(attr->name) + strlen(attr->value);
+ }
else {
/* compute size of: ' ns%d:%s="%s"' */
int ns = ns_map ? ns_map[attr->ns] : attr->ns;
@@ -733,7 +776,7 @@ static apr_size_t elem_size(const apr_xml_elem *elem, int style,
for (elem = elem->first_child; elem; elem = elem->next) {
/* the size of the child element plus the CDATA that follows it */
- size += (elem_size(elem, APR_XML_X2T_FULL, NULL, ns_map) +
+ size += (elem_size(elem, style == APR_XML_X2T_PARSED ? APR_XML_X2T_PARSED : APR_XML_X2T_FULL, NULL, ns_map) +
text_size(elem->following_cdata.first));
}
@@ -757,13 +800,15 @@ static char *write_elem(char *s, const apr_xml_elem *elem, int style,
apr_size_t len;
int ns;
- if (style == APR_XML_X2T_FULL || style == APR_XML_X2T_FULL_NS_LANG) {
+ if (style == APR_XML_X2T_FULL || style == APR_XML_X2T_FULL_NS_LANG ||
+ style == APR_XML_X2T_PARSED) {
int empty = APR_XML_ELEM_IS_EMPTY(elem);
const apr_xml_attr *attr;
- if (elem->ns == APR_XML_NS_NONE) {
+ if (elem->ns == APR_XML_NS_NONE)
len = sprintf(s, "<%s", elem->name);
- }
+ else if (style == APR_XML_X2T_PARSED)
+ len = sprintf(s, "<%s:%s", find_prefix_name(elem, elem->ns, 1), elem->name);
else {
ns = ns_map ? ns_map[elem->ns] : elem->ns;
len = sprintf(s, "<ns%d:%s", ns, elem->name);
@@ -773,10 +818,13 @@ static char *write_elem(char *s, const apr_xml_elem *elem, int style,
for (attr = elem->attr; attr; attr = attr->next) {
if (attr->ns == APR_XML_NS_NONE)
len = sprintf(s, " %s=\"%s\"", attr->name, attr->value);
- else {
- ns = ns_map ? ns_map[attr->ns] : attr->ns;
- len = sprintf(s, " ns%d:%s=\"%s\"", ns, attr->name, attr->value);
- }
+ else if (style == APR_XML_X2T_PARSED)
+ len = sprintf(s, " %s:%s=\"%s\"",
+ find_prefix_name(elem, attr->ns, 1), attr->name, attr->value);
+ else {
+ ns = ns_map ? ns_map[attr->ns] : attr->ns;
+ len = sprintf(s, " ns%d:%s=\"%s\"", ns, attr->name, attr->value);
+ }
s += len;
}
@@ -799,6 +847,18 @@ static char *write_elem(char *s, const apr_xml_elem *elem, int style,
s += len;
}
}
+ else if (style == APR_XML_X2T_PARSED) {
+ apr_xml_ns_scope *ns_scope = elem->ns_scope;
+
+ for (; ns_scope; ns_scope = ns_scope->next) {
+ const char *prefix = find_prefix_name(elem, ns_scope->ns, 0);
+
+ len = sprintf(s, " xmlns%s%s=\"%s\"",
+ *prefix ? ":" : "", *prefix ? prefix : "",
+ APR_XML_GET_URI_ITEM(namespaces, ns_scope->ns));
+ s += len;
+ }
+ }
/* no more to do. close it up and go. */
if (empty) {
@@ -823,14 +883,17 @@ static char *write_elem(char *s, const apr_xml_elem *elem, int style,
s = write_text(s, elem->first_cdata.first);
for (child = elem->first_child; child; child = child->next) {
- s = write_elem(s, child, APR_XML_X2T_FULL, NULL, ns_map);
+ s = write_elem(s, child,
+ style == APR_XML_X2T_PARSED ? APR_XML_X2T_PARSED : APR_XML_X2T_FULL,
+ NULL, ns_map);
s = write_text(s, child->following_cdata.first);
}
- if (style == APR_XML_X2T_FULL || style == APR_XML_X2T_FULL_NS_LANG) {
- if (elem->ns == APR_XML_NS_NONE) {
+ if (style == APR_XML_X2T_FULL || style == APR_XML_X2T_FULL_NS_LANG || style == APR_XML_X2T_PARSED) {
+ if (elem->ns == APR_XML_NS_NONE)
len = sprintf(s, "</%s>", elem->name);
- }
+ else if (style == APR_XML_X2T_PARSED)
+ len = sprintf(s, "</%s:%s>", find_prefix_name(elem, elem->ns, 1), elem->name);
else {
ns = ns_map ? ns_map[elem->ns] : elem->ns;
len = sprintf(s, "</ns%d:%s>", ns, elem->name);