[gxml] Fixed DomNode.lookup_prefix() and lookup_namespace_ns() with Unit Tests



commit b66933b79a5a2cb089b2c4c065ee1796b92b0810
Author: Daniel Espinosa <esodan gmail com>
Date:   Tue Jul 19 14:42:06 2016 -0500

    Fixed DomNode.lookup_prefix() and lookup_namespace_ns() with Unit Tests
    
    * Fixes require to change some behavior on setting new elements
      by using a prefix in qualifed name as namespace prefix and ns use
      a uri, just in line as DOM4 specification
    * Changed Element.set_ns_attr to use a prefix in qualifed name
      for namespace, searching for existing ones or adding a new if no
      one if found
    * Fixed a bug in Element.attrs.keys, falling an infinit loop

 gxml/Element.vala          |    4 ++--
 gxml/GXmlDocument.vala     |   14 ++++++++++++--
 gxml/GXmlElement.vala      |   43 +++++++++++++++++++++----------------------
 gxml/GXmlHashMapAttr.vala  |    1 +
 gxml/GXmlNode.vala         |   34 +++++++---------------------------
 gxml/TElement.vala         |    4 ++--
 gxml/libxml-Element.vala   |    4 ++--
 po/POTFILES.in             |    1 +
 po/POTFILES.skip           |    2 ++
 test/DomGDocumentTest.vala |   13 +++++++++++++
 test/GAttributeTest.vala   |   11 ++++++-----
 test/GDocumentTest.vala    |    4 ++--
 12 files changed, 71 insertions(+), 64 deletions(-)
---
diff --git a/gxml/Element.vala b/gxml/Element.vala
index b925c7a..27f933c 100644
--- a/gxml/Element.vala
+++ b/gxml/Element.vala
@@ -45,7 +45,7 @@ public interface GXml.Element : Object, GXml.Node
      *
      * All attributes could be get using {@link GXml.Node.attrs} property.
      */
-    public abstract GXml.Node get_attr (string name);
+    public abstract GXml.Node? get_attr (string name);
     /**
      * Search for a {@link GXml.Attribute} with given name and removes it.
      */
@@ -64,7 +64,7 @@ public interface GXml.Element : Object, GXml.Node
      * To get a attibute from {@link GXml.Node.attrs} with a given namespace
      * prefix, use "prefix:name".
      */
-    public abstract GXml.Node get_ns_attr (string name, string uri);
+    public abstract GXml.Node? get_ns_attr (string name, string uri);
     /**
      * This should be just a different name for {@link GXml.Node.name}.
      */
diff --git a/gxml/GXmlDocument.vala b/gxml/GXmlDocument.vala
index d6ab235..21cd496 100644
--- a/gxml/GXmlDocument.vala
+++ b/gxml/GXmlDocument.vala
@@ -211,8 +211,18 @@ public class GXml.GDocument : GXml.GNode,
   }
   public DomElement GXml.DomDocument.create_element_ns (string? ns, string qualified_name) throws GLib.Error
   {
-      var e = (this as GXml.Document).create_element (qualified_name);
-      e.set_namespace (ns, null);
+      string prefix = null;
+      string qname = qualified_name;
+      if (":" in qualified_name) {
+        string[] s = qualified_name.split (":");
+        if (s.length != 2) {
+          throw new DomError.INVALID_CHARACTER_ERROR (_("Invalid element qualified name: multiple namespace 
prefixes"));
+        }
+        prefix = s[0];
+        qname = s[1];
+      }
+      var e = (this as GXml.Document).create_element (qname);
+      e.set_namespace (ns, prefix);
       return e as DomElement;
   }
 
diff --git a/gxml/GXmlElement.vala b/gxml/GXmlElement.vala
index 60be4c0..1adc25a 100644
--- a/gxml/GXmlElement.vala
+++ b/gxml/GXmlElement.vala
@@ -49,10 +49,10 @@ public class GXml.GElement : GXml.GNonDocumentChildNode,
     if (":" in aname) return;
     _node->set_prop (aname, avalue);
   }
-  public GXml.Node get_attr (string name)
+  public GXml.Node? get_attr (string name)
   {
     if (_node == null) return null;
-    string prefix = "";
+    string prefix = null;
     string n = name;
     if (":" in name) {
       string[] pp = name.split (":");
@@ -60,39 +60,38 @@ public class GXml.GElement : GXml.GNonDocumentChildNode,
       prefix = pp[0];
       n = pp[1];
     }
-    var ps = _node->properties;
-    while (ps != null) {
-      if (ps->name == n) {
-        if (ps->ns == null && prefix == "") return new GAttribute (_doc, ps);
-        if (ps->ns == null) continue;
-        if (ps->ns->prefix == prefix)
-          return new GAttribute (_doc, ps);
-      }
-      ps = ps->next;
+    if (prefix != null) {
+      var ns = _node->doc->search_ns (_node, prefix);
+      if (ns == null) return null;
+      var nsa = _node->has_ns_prop (n,ns->href);
+      if (nsa == null) return null;
+      return new GAttribute (_doc, nsa);
     }
-    return null;
+    var p = _node->has_prop (n);
+    if (p == null) return null;
+    return new GAttribute (_doc, p);
   }
   public void set_ns_attr (string ns, string name, string value) {
     if (_node == null) return;
     string prefix = null;
-    string uri = "";
-    if (":" in ns) {
+    string qname = name;
+    if (":" in name) {
       string[] s = ns.split(":");
+      if (s.length != 2) return;
       prefix = s[0];
-      uri = s[1];
-    } else
-      uri = ns;
-    var ins = _node->doc->search_ns (_node, prefix);
+      qname = s[1];
+    }
+    var ins = _node->doc->search_ns_by_href (_node, ns);
     if (ins != null) {
-      _node->set_ns_prop (ins, name, value);
+      _node->set_ns_prop (ins, qname, value);
       return;
     }
-    var nns = _node->new_ns (uri, prefix);
+    var nns = _node->new_ns (ns, prefix);
     if (nns != null) {
-      _node->set_ns_prop (nns, name, value);
+      _node->set_ns_prop (nns, qname, value);
     }
   }
-  public GXml.Node get_ns_attr (string name, string uri) {
+  public GXml.Node? get_ns_attr (string name, string uri) {
     if (_node == null) return null;
     var a = _node->has_ns_prop (name, uri);
     if (a == null) return null;
diff --git a/gxml/GXmlHashMapAttr.vala b/gxml/GXmlHashMapAttr.vala
index 391ae88..12d247d 100644
--- a/gxml/GXmlHashMapAttr.vala
+++ b/gxml/GXmlHashMapAttr.vala
@@ -129,6 +129,7 @@ public class GXml.GHashMapAttr : Gee.AbstractMap<string,GXml.Node>,
       var p = _node->properties;
       while (p != null) {
         l.add (p->name.dup ());
+        p = p->next;
       }
       return l;
     }
diff --git a/gxml/GXmlNode.vala b/gxml/GXmlNode.vala
index df45f8c..12891cf 100644
--- a/gxml/GXmlNode.vala
+++ b/gxml/GXmlNode.vala
@@ -264,38 +264,18 @@ public abstract class GXml.GNode : Object,
   }
 
   public string? lookup_prefix (string? nspace) {
+    if (_node == null) return null;
     if (parent == null) return null;
     if (this is GXml.DocumentType || this is GXml.DocumentFragment) return null;
-    if (this is GXml.Document)
-      if ((this as GXml.Document).root != null)
-        return (document.root as DomNode).lookup_prefix (nspace);
-      else
-        return null;
-    if (this is GXml.Element) {
-      if (namespaces.size > 0) {
-        var ns = namespaces[0];
-        if (ns.prefix == nspace) return ns.uri;
-        else return null;
-      }
-    }
-    return (this.parent as GXml.DomNode).lookup_prefix (nspace);
+    var ns = _node->doc->search_ns_by_href (_node, nspace);
+    if (ns == null) return null;
+    return ns->prefix;
   }
   public string? lookup_namespace_uri (string? prefix) {
-    if (prefix == null) return null;
     if (this is GXml.DocumentType || this is GXml.DocumentFragment) return null;
-    if (this is GXml.Document)
-      if ((this as GXml.Document).root != null)
-        return (document.root as DomNode).lookup_namespace_uri (prefix);
-      else
-        return null;
-    if (this is GXml.Element) {
-      if (namespaces.size > 0) {
-        var ns = namespaces[0];
-        if (ns.prefix == prefix) return ns.uri;
-        else return null;
-      }
-    }
-    return (this.parent as GXml.DomNode).lookup_namespace_uri (prefix);
+    var ns = _node->doc->search_ns (_node, prefix);
+    if (ns == null) return null;
+    return ns->href;
   }
   public bool is_default_namespace (string? nspace) {
     if (nspace == null) return false;
diff --git a/gxml/TElement.vala b/gxml/TElement.vala
index 2c97e7c..a63db21 100644
--- a/gxml/TElement.vala
+++ b/gxml/TElement.vala
@@ -71,8 +71,8 @@ public class GXml.TElement : GXml.TNode, GXml.Element
     att.set_parent (this);
     attrs.set (name, att);
   }
-  public GXml.Node get_attr (string name) { return attrs.get (name); }
-  public GXml.Node get_ns_attr (string name, string uri) {
+  public GXml.Node? get_attr (string name) { return attrs.get (name); }
+  public GXml.Node? get_ns_attr (string name, string uri) {
     foreach (string k in attrs.keys) {
       if (!(":" in k)) continue;
       var a = attrs.get (k);
diff --git a/gxml/libxml-Element.vala b/gxml/libxml-Element.vala
index 16ef98b..908d6d4 100644
--- a/gxml/libxml-Element.vala
+++ b/gxml/libxml-Element.vala
@@ -476,8 +476,8 @@ namespace GXml {
                }
                // GXml.Element interface
     public void set_attr (string name, string value) { set_attribute (name, value); }
-    public GXml.Node get_attr (string name) { return (GXml.Node) get_attribute_node (name); }
-               public GXml.Node get_ns_attr (string name, string uri) {
+    public GXml.Node? get_attr (string name) { return (GXml.Node) get_attribute_node (name); }
+               public GXml.Node? get_ns_attr (string name, string uri) {
                  if (node == null) return null;
                  var a = node->has_ns_prop (name, uri);
                  if (a == null) return null;
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 617581c..489ad8f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -25,3 +25,4 @@ gxml/SerializableObjectModel.vala
 gxml/SerializableProperty.vala
 gxml/Serializable.vala
 gxml/TDocument.vala
+gxml/GXmlNode.vala
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index f8256a5..df7f18e 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -25,6 +25,7 @@ gxml/SerializableGeeTreeMap.c
 gxml/SerializableObjectModel.c
 gxml/SerializableProperty.c
 gxml/TDocument.c
+gxml/GXmlNode.c
 sub/gxml/Document.c
 sub/gxml/DomCharacter.c
 sub/gxml/Enumeration.c
@@ -50,3 +51,4 @@ sub/gxml/SerializableGeeTreeMap.c
 sub/gxml/SerializableObjectModel.c
 sub/gxml/SerializableProperty.c
 sub/gxml/TDocument.c
+sub/gxml/GXmlNode.c
diff --git a/test/DomGDocumentTest.vala b/test/DomGDocumentTest.vala
index c813a06..611e06d 100644
--- a/test/DomGDocumentTest.vala
+++ b/test/DomGDocumentTest.vala
@@ -182,6 +182,19 @@ static const string HTMLDOC ="
                        assert (e1.compare_document_position (e1.parent_node) == 
(DomNode.DocumentPosition.CONTAINS & DomNode.DocumentPosition.FOLLOWING));
                        assert (e1.contains (e1.child_nodes[0]));
                        assert (e1.compare_document_position (e1.child_nodes[0]) == 
(DomNode.DocumentPosition.CONTAINED_BY & DomNode.DocumentPosition.PRECEDING));
+                       var b = doc.document_element.children[0];
+                       assert (b.node_name == "body");
+                       var ng = doc.create_element_ns ("http://git.gnome.org/browse/gxml","gxml:MyNode";);
+                       b.child_nodes.add (ng);
+                       assert (ng.lookup_prefix ("http://git.gnome.org/browse/gxml";) == "gxml");
+                       assert (ng.lookup_namespace_uri ("gxml") == "http://git.gnome.org/browse/gxml";);
+                       assert (!ng.is_default_namespace ("gxml:http://git.gnome.org/browse/gxml";));
+                       var ng2 = doc.create_element_ns ("http://live.gnome.org/GXml";, "OtherNode");
+                       b.child_nodes.add (ng2);
+                       GLib.message ("BODY:"+(b as GXml.Node).to_string ());
+                       assert (ng2.lookup_prefix ("http://live.gnome.org/GXml";) == null);
+                       assert (ng2.lookup_namespace_uri (null) == "http://live.gnome.org/GXml";);
+                       assert (ng2.is_default_namespace ("http://live.gnome.org/GXml";));
                });
        }
 }
diff --git a/test/GAttributeTest.vala b/test/GAttributeTest.vala
index 5737d71..54cc94c 100644
--- a/test/GAttributeTest.vala
+++ b/test/GAttributeTest.vala
@@ -82,7 +82,7 @@ class GAttributeTest : GXmlTest {
                });
                Test.add_func ("/gxml/gattribute/namespace_value", () => {
                        try {
-                               GDocument doc = new GDocument.from_string ("<Wands 
xmlns:wands=\"http://mom.co.uk/wands\";><Wand price=\"43.56\" wands:core=\"dragon heart cord\" 
wands:shell=\"oak\" shell=\"NoNs\"/></Wands>");
+                               GDocument doc = new GDocument.from_string ("<Wands xmlns=\"http://gxml.org/\"; 
xmlns:wands=\"http://mom.co.uk/wands\";><Wand price=\"43.56\" wands:core=\"dragon heart cord\" 
wands:shell=\"oak\" cshell=\"NoNs\"/></Wands>");
                                // User namespace prefix to find namespaced attribute
                                var nspshell = ((GElement) doc.root.children_nodes[0]).get_attr 
("wands:shell") as GAttribute;
                                assert (nspshell != null);
@@ -100,15 +100,16 @@ class GAttributeTest : GXmlTest {
                                assert (nspshell2.namespace.uri == "http://mom.co.uk/wands";);
                                assert (nspshell2.value == "oak");
                                // User no namespaced attribute
-                               var shell = ((GElement) doc.root.children_nodes[0]).get_attr ("shell") as 
GAttribute;
+                               var shell = ((GElement) doc.root.children_nodes[0]).get_attr ("cshell") as 
GAttribute;
                                assert (shell != null);
-                               assert (shell.name == "shell");
+                               assert (shell is Attribute);
+                               assert (shell.name == "cshell");
                                assert (shell.namespace == null);
                                assert (shell.value == "NoNs");
                                // User no namespaced from Node.attrs
-                               var shell2 = doc.root.children_nodes[0].attrs.get ("shell") as GAttribute;
+                               var shell2 = doc.root.children_nodes[0].attrs.get ("cshell") as GAttribute;
                                assert (shell2 != null);
-                               assert (shell2.name == "shell");
+                               assert (shell2.name == "cshell");
                                assert (shell2.namespace == null);
                                assert (shell2.value == "NoNs");
                        } catch (GLib.Error e) {
diff --git a/test/GDocumentTest.vala b/test/GDocumentTest.vala
index 5eed22a..601bcc7 100644
--- a/test/GDocumentTest.vala
+++ b/test/GDocumentTest.vala
@@ -331,13 +331,13 @@ class GDocumentTest : GXmlTest {
                                assert (p == null);
                                Test.message ("ROOT: "+doc.root.to_string ());
                                assert (doc.root.to_string () == "<root 
xmlns:gxml=\"http://www.gnome.org/GXml\";><child xmlns:gxml2=\"http://www.gnome.org/GXml2\"/></root>");
-                               (c as Element).set_ns_attr 
(doc.root.namespaces[0].prefix+":"+doc.root.namespaces[0].uri, "prop", "Ten");
+                               (c as Element).set_ns_attr (doc.root.namespaces[0].uri, "prop", "Ten");
                                Test.message ("ROOT: "+doc.root.to_string ());
                                assert (c.attrs.size == 1);
                                var pt = c.attrs.get ("prop");
                                assert (pt != null);
                                var pt2 = (c as Element).get_ns_attr ("prop", doc.root.namespaces[0].uri);
-                               Test.message ("ROOT: "+doc.root.to_string ());
+                               GLib.message ("ROOT: "+doc.root.to_string ());
                                assert (doc.root.to_string () == "<root 
xmlns:gxml=\"http://www.gnome.org/GXml\";><child xmlns:gxml2=\"http://www.gnome.org/GXml2\"; 
gxml:prop=\"Ten\"/></root>");
                        } catch (GLib.Error e) {
                                GLib.message ("ERROR: "+ e.message);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]