summaryrefslogtreecommitdiff
path: root/xml
diff options
context:
space:
mode:
authorGraham Leggett <minfrin@apache.org>2016-06-12 00:02:22 +0000
committerGraham Leggett <minfrin@apache.org>2016-06-12 00:02:22 +0000
commitafb05ba52d4c344e41a43c54161943e36a84f37d (patch)
tree76c1c4a686d577de873916141230da100e5ec653 /xml
parent63225f69079607e4b3438c491629435d9256e07b (diff)
downloadapr-afb05ba52d4c344e41a43c54161943e36a84f37d.tar.gz
apr_xml_to_text: Add style APR_XML_X2T_PARSED to maintain a consistent namespace prefix.
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1747941 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'xml')
-rw-r--r--xml/apr_xml.c82
1 files changed, 76 insertions, 6 deletions
diff --git a/xml/apr_xml.c b/xml/apr_xml.c
index 8ea2b32fe..82791f49d 100644
--- a/xml/apr_xml.c
+++ b/xml/apr_xml.c
@@ -97,6 +97,25 @@ 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;
@@ -538,7 +557,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;
@@ -562,11 +582,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;
@@ -592,6 +630,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;
@@ -625,7 +667,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));
}
@@ -649,13 +691,17 @@ 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) {
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);
@@ -663,8 +709,13 @@ static char *write_elem(char *s, const apr_xml_elem *elem, int style,
s += len;
for (attr = elem->attr; attr; attr = attr->next) {
- if (attr->ns == APR_XML_NS_NONE)
+ if (attr->ns == APR_XML_NS_NONE) {
len = sprintf(s, " %s=\"%s\"", 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);
@@ -692,6 +743,19 @@ static char *write_elem(char *s, const apr_xml_elem *elem, int style,
}
}
+ 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) {
*s++ = '/';
@@ -715,14 +779,20 @@ 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 (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);