[gxml] Fixes on namespaces handling
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gxml] Fixes on namespaces handling
- Date: Thu, 3 Nov 2016 00:02:27 +0000 (UTC)
commit 4dc0506ff1253543522781229e4393649f661a44
Author: Daniel Espinosa <esodan gmail com>
Date: Wed Nov 2 15:19:33 2016 -0600
Fixes on namespaces handling
Fixes on lookup namespaces' prefix and URI
Fixes on XParser reading namespaces on elements
Simplified getting namespaced attributes
Added some Unit Tests for namespaces
gxml/GomDocument.vala | 2 +-
gxml/GomElement.vala | 162 +++++++++++++++++++++++++++-------------------
gxml/XParser.vala | 18 ++++--
test/GomElementTest.vala | 17 ++++-
4 files changed, 123 insertions(+), 76 deletions(-)
---
diff --git a/gxml/GomDocument.vala b/gxml/GomDocument.vala
index d99b030..c931cad 100644
--- a/gxml/GomDocument.vala
+++ b/gxml/GomDocument.vala
@@ -109,7 +109,7 @@ public class GXml.GomDocument : GomNode,
if (":" in qualified_name) {
var s = qualified_name.split (":");
if (s.length != 2)
- throw new DomError.NOT_SUPPORTED_ERROR (_("Invalid node name"));
+ throw new DomError.NAMESPACE_ERROR (_("Invalid node name"));
nsp = s[0];
n = s[1];
} else
diff --git a/gxml/GomElement.vala b/gxml/GomElement.vala
index ff71140..abaa0fb 100644
--- a/gxml/GomElement.vala
+++ b/gxml/GomElement.vala
@@ -35,17 +35,25 @@ public class GXml.GomElement : GomNode,
protected Attributes _attributes;
// DomNode overrides
public new string? lookup_prefix (string? nspace) {
- if (_namespace_uri == nspace && _prefix != null)
+ if (_namespace_uri == nspace)
return _prefix;
foreach (string k in _attributes.keys) {
- var a = _attributes.get_named_item (k);
- if (a == null) {
- GLib.warning (_("Attribute: %s not found").printf (k));
- continue;
+ if (!("xmlns" in k)) continue;
+ string ns_uri = _attributes.get (k);
+ if (ns_uri == null) {
+ GLib.warning (_("Invalid namespace URI stored in element's attribute"));
+ return null;
+ }
+ if (ns_uri == nspace) {
+ if (":" in k) {
+ string[] sa = k.split (":");
+ if (sa.length > 2) {
+ GLib.warning (_("Invalid attribute name in element's attributes list"));
+ return null;
+ }
+ return sa[1];
+ }
}
- if ((a as DomAttr).prefix == null) continue;
- if ((a as DomAttr).prefix.down () == "xmlns" && a.node_value == nspace)
- return (a as DomAttr).local_name;
}
if (parent_node == null) return null;
return parent_node.lookup_prefix (nspace);
@@ -56,21 +64,19 @@ public class GXml.GomElement : GomNode,
string s = "";
if (prefix != null) s = prefix;
foreach (string k in attributes.keys) {
- var a = _attributes.get_named_item (k);
- if (a == null) {
- GLib.warning (_("Attribute: %s not found").printf (k));
- continue;
+ if (!("xmlns" in k)) continue;
+ GLib.message ("Attribute: "+k);
+ string nsp = null;
+ if (":" in k) {
+ string[] sa = k.split (":");
+ if (sa.length > 2) {
+ GLib.warning (_("Invalid attribute name in element's attributes list"));
+ return null;
+ }
+ nsp = sa[1];
}
- if ((a as DomAttr).namespace_uri == "http://www.w3.org/2000/xmlns/")
- if ((a as DomAttr).prefix == "xmlns"
- && a.node_name == s)
- return a.node_value;
- if (((a as DomAttr).prefix == null || (a as DomAttr).prefix == "")
- && s == ""
- && a.node_name == "xmlns"
- && (a as DomAttr).namespace_uri == "http://www.w3.org/2000/xmlns/"
- && (prefix == null || prefix == ""))
- return a.node_value;
+ if (nsp != prefix) continue;
+ return _attributes.get (k);
}
if (parent_node == null) return null;
return parent_node.lookup_namespace_uri (prefix);
@@ -174,8 +180,10 @@ public class GXml.GomElement : GomNode,
string? prefix, string local_name) {
_document = doc;
_local_name = local_name;
+ _namespace_uri = namespace_uri;
+ _prefix = prefix;
var a = new GomAttr.namespace (this, "http://www.w3.org/2000/xmlns/",
- prefix, "xmlns", namespace_uri);
+ "xmlns", prefix, namespace_uri);
_attributes.set_named_item_ns (a);
}
/**
@@ -196,7 +204,7 @@ public class GXml.GomElement : GomNode,
if (name == "") return null;
string p = "";
string ns = null;
- string n = "";
+ string n = name;
if (":" in name) {
string[] s = name.split (":");
if (s.length > 2) return null;
@@ -211,9 +219,10 @@ public class GXml.GomElement : GomNode,
if (val == null) return null;
DomNode attr = null;
if (p == null || p == "")
- attr = new GomAttr (_element, name, val);
+ attr = new GomAttr (_element, n, val);
else
attr = new GomAttr.namespace (_element, ns, p, n, val);
+ GLib.message ("Return: "+ attr.node_name+"="+attr.node_value);
return attr;
}
/**
@@ -276,46 +285,66 @@ public class GXml.GomElement : GomNode,
|| (node as DomAttr).prefix == null
&& node.node_name != "xmlns")
throw new DomError.NAMESPACE_ERROR (_("Namespaced attributes should provide a valid prefix and
namespace"));
- string nsp = "";
+ if ((node as DomAttr).prefix == "xmlns"
+ && node.node_name == "xmlns")
+ throw new DomError.NAMESPACE_ERROR (_("Invalid namespace attribute's name."));
GLib.message ("Searching for duplicated ns..."+node.node_value);
- if ((node as DomAttr).prefix == "xmlns")
+ if ((node as DomAttr).prefix == "xmlns"
+ || (node as DomAttr).local_name == "xmlns") {
+ string asp = _element.get_attribute_ns (node.node_value,
+ (node as DomAttr).local_name);
+ if (asp != null) return node;
+ }
+ string nsp, ns_uri, sp;
+ sp = nsp = ns_uri = "";
+ if (node.node_name == "xmlns"
+ && ((node as DomAttr).prefix == null
+ || (node as DomAttr).prefix == "")) {
+
+ if ((node as DomAttr).prefix == "xmlns") {
+ sp = node.node_name;
+ }
+#if DEBUG
+ if (_element.prefix != null)
+ GLib.message ("Node Element prefix: "+_element.prefix);
+ if (_element.namespace_uri != null)
+ GLib.message ("Node Element namespace URI: "+_element.namespace_uri);
+#endif
nsp = _element.lookup_prefix (node.node_value);
- GLib.message ("Searching for duplicated ns...");
- if ((node as DomAttr).prefix != "xmlns")
- nsp = _element.lookup_prefix ((node as DomAttr).namespace_uri);
- GLib.message ("Searching for duplicated ns...");
- if (nsp != null)
- GLib.message ("Found PREFIX: "+nsp+" Node prefix: "+(node as DomAttr).prefix+
- " Node name: "+node.node_name+"Node Value: "+node.node_value);
- GLib.message ("Searching for duplicated ns...");
- if ((node as DomAttr).prefix == "xmlns" && node.node_name != nsp
- || (((node as DomAttr).prefix != "xmlns")
- && (node as DomAttr).prefix != nsp)) {
- string snsp = "";
- if (nsp != null) snsp = ": "+nsp;
- GLib.message ("Duplicated ns");
- GLib.message ("Found Duplicated ns"+snsp);
- throw new DomError.NAMESPACE_ERROR (_("Attribute's prefix and namespace URI conflics with already
defined namespace%s").printf (snsp));
+ ns_uri = _element.lookup_namespace_uri (nsp);
+ if (ns_uri != null &&
+ ns_uri != node.node_value)
+ throw new DomError.NAMESPACE_ERROR
+ (_("Namespace's prefix Redefinition for %s")
+ .printf (ns_uri));
}
+
string p = "";
if ((node as DomAttr).prefix != null
- && (node as DomAttr).prefix != "") p = (node as DomAttr).prefix + ":";
+ && (node as DomAttr).prefix != "")
+ p = (node as DomAttr).prefix + ":";
+ GLib.message ("Attribute to set: "+p+(node as DomAttr).local_name
+ +"="+node.node_value);
set (p+(node as DomAttr).local_name,
node.node_value);
+
+ if ((node as DomAttr).prefix != "xmlns"
+ && ((node as DomAttr).namespace_uri != "http://www.w3.org/2000/xmlns/"
+ && (node as DomAttr).namespace_uri != "http://www.w3.org/2000/xmlns")
+ && node.node_name != "xmlns"
+ && ns_uri == null) {
+ string nsn = "xmlns";
+ if ((node as DomAttr).prefix != null
+ && (node as DomAttr).prefix != "")
+ nsn = "xmlns:"+(node as DomAttr).prefix;
+ _element.set_attribute_ns ("http://www.w3.org/2000/xmlns/",
+ nsn, (node as DomAttr).namespace_uri);
+ }
+
var attr = new GomAttr.namespace (_element,
(node as DomAttr).namespace_uri,
(node as DomAttr).prefix,
node.node_name, node.node_value);
- if (_element.prefix != null)
- GLib.message ("Node Element prefix: "+_element.prefix);
- if (_element.namespace_uri != null)
- GLib.message ("Node Element namespace URI: "+_element.namespace_uri);
- if ((node as DomAttr).prefix != "xmlns"
- && ((node as DomAttr).namespace_uri == "http://www.w3.org/2000/xmlns/"
- || (node as DomAttr).namespace_uri == "http://www.w3.org/2000/xmlns")
- && _element.prefix == null && _element.namespace_uri == null)
- _element.set_attribute_ns ("http://www.w3.org/2000/xmlns/","xmlns",
- (node as DomAttr).namespace_uri);
return attr;
}
}
@@ -323,20 +352,19 @@ public class GXml.GomElement : GomNode,
public string? get_attribute (string name) {
string s = (this as GomObject).get_attribute (name);
if (s != null) return s;
- var a = _attributes.get_named_item (name);
- if (a == null) return null;
- return a.node_value;
+ return _attributes.get (name);
}
- public string? get_attribute_ns (string? namespace, string local_name) {
- DomNode p = null;
- try { p = _attributes.get_named_item_ns (namespace, local_name); }
- catch (GLib.Error e) {
- string s = _("Error:");
- GLib.warning (s+e.message);
- return null;
- }
- if (p == null) return null;
- return p.node_value;
+ public string? get_attribute_ns (string? namespace_uri, string local_name) {
+ string nsp = null;
+ if (namespace_uri == "http://www.w3.org/2000/xmlns/"
+ && local_name != "xmlns")
+ nsp = "xmlns";
+ else
+ nsp = lookup_prefix (namespace_uri);
+ string name = local_name;
+ if (nsp != null)
+ name = nsp + ":" + local_name;
+ return _attributes.get (name);
}
public void set_attribute (string name, string value) throws GLib.Error {
bool res = (this as GomObject).set_attribute (name, value);
diff --git a/gxml/XParser.vala b/gxml/XParser.vala
index f1adb6d..ab65ecb 100644
--- a/gxml/XParser.vala
+++ b/gxml/XParser.vala
@@ -107,8 +107,9 @@ public class GXml.XParser : Object, GXml.Parser {
#endif
prefix = tr.prefix ();
if (prefix != null) {
+ GLib.message ("Is namespaced element");
nsuri = tr.lookup_namespace (prefix);
- n = _document.create_element_ns (nsuri, tr.prefix () + tr.const_local_name ());
+ n = _document.create_element_ns (nsuri, tr.prefix () +":"+ tr.const_local_name ());
} else
n = _document.create_element (tr.const_local_name ());
node.append_child (n);
@@ -125,15 +126,20 @@ public class GXml.XParser : Object, GXml.Parser {
throw new DomError.HIERARCHY_REQUEST_ERROR (_("Parsing ERROR: Fail to move to attribute number:
%i").printf (i));
}
if (tr.is_namespace_decl () == 1) {
-#if DEBUG
+//#if DEBUG
GLib.message ("Is Namespace Declaration...");
-#endif
+//#endif
string nsp = tr.const_local_name ();
- prefix = tr.prefix ();
+ string aprefix = tr.prefix ();
tr.read_attribute_value ();
if (tr.node_type () == Xml.ReaderType.TEXT) {
- nsuri = tr.read_string ();
- (n as DomElement).set_attribute_ns (nsuri, prefix+":"+nsp, nsuri);
+ string ansuri = tr.read_string ();
+ GLib.message ("Read: "+aprefix+":"+nsp+"="+ansuri);
+ string ansp = "";
+ if (nsp != "xmlns")
+ ansp = aprefix+":"+nsp;
+ (n as DomElement).set_attribute_ns ("http://www.w3.org/2000/xmlns/",
+ ansp, ansuri);
}
} else {
var attrname = tr.const_local_name ();
diff --git a/test/GomElementTest.vala b/test/GomElementTest.vala
index 627c8d3..36c8d0c 100644
--- a/test/GomElementTest.vala
+++ b/test/GomElementTest.vala
@@ -32,13 +32,26 @@ class GomElementTest : GXmlTest {
assert (root.node_name == "Potions");
GXml.GomNode node = (GXml.GomNode) root.child_nodes[0];
assert (node != null);
- assert (node.node_name == "Potion");
+ assert (node is DomElement);
+ assert ((node as DomElement).local_name == "Potion");
+ assert (node.node_name == "magic:Potion");
assert ((node as DomElement).namespace_uri == "http://hogwarts.co.uk/magic");
assert ((node as DomElement).prefix == "magic");
+ assert ((node as DomElement).attributes.size == 2);
+ GLib.message ("Attributes: "+(node as DomElement).attributes.size.to_string
());
+ /*foreach (string k in (node as DomElement).attributes.keys) {
+ string v = (node as DomElement).get_attribute (k);
+ if (v == null) v = "NULL";
+ GLib.message ("Attribute: "+k+"="+v);
+ }*/
+ assert ((node as DomElement).get_attribute ("xmlns:magic") ==
"http://hogwarts.co.uk/magic");
+ assert ((node as DomElement).get_attribute_ns
("http://www.w3.org/2000/xmlns/", "magic") == "http://hogwarts.co.uk/magic");
+ assert ((node as DomElement).get_attribute ("xmlns:products") ==
"http://diagonalley.co.uk/products");
+ assert ((node as DomElement).get_attribute_ns
("http://www.w3.org/2000/xmlns/","products") == "http://diagonalley.co.uk/products");
assert (node.lookup_prefix ("http://diagonalley.co.uk/products") ==
"products");
assert (node.lookup_namespace_uri ("products") ==
"http://diagonalley.co.uk/products");
} catch (GLib.Error e) {
- Test.message (e.message);
+ GLib.message (e.message);
assert_not_reached ();
}
});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]