[gxml] GomElement, Parser: Fix parse namespaced attributes



commit a3686c7515bd814aae5876e328b758e8fa5c4b8c
Author: Daniel Espinosa <esodan gmail com>
Date:   Mon Oct 30 17:11:52 2017 -0600

    GomElement, Parser: Fix parse namespaced attributes

 gxml/GomCollections.vala       |    3 +-
 gxml/GomElement.vala           |    5 +-
 gxml/GomObject.vala            |   19 ----
 gxml/Parser.vala               |    1 +
 gxml/XParser.vala              |    4 +-
 test/GomElementTest.vala       |  177 +++++++++++++++++++++++++++++++++++++++-
 test/GomSerializationTest.vala |    2 -
 7 files changed, 183 insertions(+), 28 deletions(-)
---
diff --git a/gxml/GomCollections.vala b/gxml/GomCollections.vala
index d653f9d..a91582d 100644
--- a/gxml/GomCollections.vala
+++ b/gxml/GomCollections.vala
@@ -238,7 +238,8 @@ public abstract class GXml.BaseCollection : Object {
     if (node.owner_document != _element.owner_document)
       throw new DomError.HIERARCHY_REQUEST_ERROR
                 (_("Invalid attempt to set a node with a different parent document"));
-    _element.append_child (node);
+    if (node.parent_node == null)
+      _element.append_child (node);
     if (_element.child_nodes.size == 0)
       throw new DomError.QUOTA_EXCEEDED_ERROR
                 (_("Node element not appended as child of parent. No node added to collection"));
diff --git a/gxml/GomElement.vala b/gxml/GomElement.vala
index f80dced..4f5811f 100644
--- a/gxml/GomElement.vala
+++ b/gxml/GomElement.vala
@@ -406,9 +406,6 @@ public class GXml.GomElement : GomNode,
       else
         attr = new GomAttr.namespace (_element, ns, p, n, val);
 
-#if DEBUG
-      GLib.message ("Return: "+ attr.node_name+"="+attr.node_value);
-#endif
       return attr;
     }
     /**
@@ -507,7 +504,7 @@ public class GXml.GomElement : GomNode,
         if (nspn != (node as DomAttr).prefix
             && nsn != (node as DomAttr).namespace_uri)
           throw new DomError.NAMESPACE_ERROR
-                  (_("Trying to add an attribute with an undefined namespace prefix"));
+                  (_("Trying to add an attribute with an undefined namespace prefix: %s").printf ((node as 
DomAttr).prefix));
         nspn = _element.lookup_prefix ((node as DomAttr).namespace_uri);
         nsn = _element.lookup_namespace_uri (nspn);
         if (nspn != (node as DomAttr).prefix
diff --git a/gxml/GomObject.vala b/gxml/GomObject.vala
index e718aff..0e10e00 100644
--- a/gxml/GomObject.vala
+++ b/gxml/GomObject.vala
@@ -57,16 +57,9 @@ public interface GXml.GomObject : GLib.Object,
   public virtual ParamSpec? find_property_name (string pname) {
     foreach (ParamSpec spec in this.get_class ().list_properties ()) {
       string name = spec.get_nick ();
-#if DEBUG
-          GLib.message ("Name: "+spec.name+ " Nick: "+spec.get_nick ()+" Type: "+spec.value_type.name());
-#endif
       if ("::" in name) {
         name = name.replace ("::","");
         if (name.down () == pname.down ()) {
-#if DEBUG
-          GLib.message ("Found Property: "+pname);
-          GLib.message ("Is GomProperty? : "+(spec.value_type.is_a (typeof(GomProperty)).to_string ()));
-#endif
           return spec;
         }
       }
@@ -191,14 +184,8 @@ public interface GXml.GomObject : GLib.Object,
    * this object, see {@link get_child}
    */
   public virtual string? get_attribute (string name) {
-#if DEBUG
-    GLib.message ("Searching GomObject attribute: "+name);
-#endif
     var prop = find_property_name (name);
     if (prop == null) return null;
-#if DEBUG
-    GLib.message ("Found GomObject attribute: "+prop.name);
-#endif
     return get_property_string (prop);
   }
   /**
@@ -211,13 +198,7 @@ public interface GXml.GomObject : GLib.Object,
    * this object.
    */
   public virtual bool set_attribute (string name, string val) {
-#if DEBUG
-    GLib.message ("GomObject: searching attribute to set: "+name);
-#endif
     var prop = find_property_name (name);
-#if DEBUG
-    GLib.message ("GomObject: setting attribute: "+name);
-#endif
     if (prop != null) {
       var v = Value (prop.value_type);
       if (prop.value_type.is_a (typeof(GomProperty))
diff --git a/gxml/Parser.vala b/gxml/Parser.vala
index 1fa1f4e..45e3a5f 100644
--- a/gxml/Parser.vala
+++ b/gxml/Parser.vala
@@ -275,6 +275,7 @@ public interface GXml.Parser : Object {
                       (_("No document is set to node"));
         var obj = Object.new (col.items_type,
                               "owner-document", node.owner_document) as DomElement;
+        parent.append_child (obj);
         read_element (obj as DomElement);
         col.append (obj);
         element = obj;
diff --git a/gxml/XParser.vala b/gxml/XParser.vala
index f258239..aebdc8b 100644
--- a/gxml/XParser.vala
+++ b/gxml/XParser.vala
@@ -290,8 +290,10 @@ public class GXml.XParser : Object, GXml.Parser {
         if (tr.node_type () == Xml.ReaderType.TEXT) {
           var attrval = tr.read_string ();
           bool processed = false;
+          string attn = attrname;
+          if (prefix != null) attn = prefix+":"+attrname;
           if (node is GomObject) {
-            processed = (element as GomObject).set_attribute (attrname, attrval);
+            processed = (element as GomObject).set_attribute (attn, attrval);
           }
           if (!processed) {
             if (prefix != null) {
diff --git a/test/GomElementTest.vala b/test/GomElementTest.vala
index ba7a8ce..9376e54 100644
--- a/test/GomElementTest.vala
+++ b/test/GomElementTest.vala
@@ -69,11 +69,114 @@ class GomElementTest : GXmlTest  {
                public Property pq { get; set; }
                construct { initialize ("Top"); }
        }
+       public class Potion : GomElement {
+               [Description (nick="::c:name")]
+               public string cname { get; set; }
+               public Ingredient ingredient { get; set; }
+               construct {
+                       initialize ("Potion");
+                       try {
+                               set_attribute_ns ("http://www.w3.org/2000/xmlns";, 
"xmlns:c","http://c.org/1.0";);
+                       } catch (GLib.Error e) { warning ("Error: "+e.message); }
+               }
+       }
+       public class Ingredient : GomElement, MappeableElement {
+               [Description (nick="::c:name")]
+               public string cname { get; set; }
+               public Method.Map methods { get; set; }
+               construct { initialize ("ingredient"); }
+               public string get_map_key () { return cname; }
+               public class Map : GomHashMap {
+                       construct {
+                               try {
+                                       initialize (typeof (Ingredient));
+                               } catch (GLib.Error e) { warning ("Error: "+e.message); }
+                       }
+               }
+       }
+       public class Method : GomElement, MappeableElement {
+               [Description (nick="::c:name")]
+               public string cname { get; set; }
+               construct { initialize ("method"); }
+               public string get_map_key () { return cname; }
+               public class Map : GomHashMap {
+                       construct {
+                               try {
+                                       initialize (typeof (Method));
+                               } catch (GLib.Error e) { warning ("Error: "+e.message); }
+                       }
+               }
+       }
+       public class Repository : GomElement
+ {
+    [Description (nick="::version")]
+    public string version { get; set; }
+
+    public Namespace ns { get; set; }
+
+    construct {
+      initialize ("repository");
+      set_attribute_ns ("http://www.w3.org/2000/xmlns";,
+                      "xmlns", "http://www.gtk.org/introspection/core/1.0";);
+      set_attribute_ns ("http://www.w3.org/2000/xmlns";,
+                      "xmlns:c", "http://www.gtk.org/introspection/c/1.0";);
+      set_attribute_ns ("http://www.w3.org/2000/xmlns";,
+                        "xmlns:glib", "http://www.gtk.org/introspection/glib/1.0";);
+      version = "1.2";
+    }
+ }
+ public class Namespace : GomElement
+ {
+    TClass.Map _classes;
+    [Description (nick="::name")]
+    public string name { get; set; }
+    [Description (nick="::version")]
+    public string version { get; set; }
+    [Description (nick="::c:prefix")]
+    public string cprefix { get; set; }
+    public TClass.Map classes {
+      get {
+        if (_classes == null)
+          set_instance_property ("classes");
+        return _classes;
+      }
+      set {
+        if (_classes != null)
+          clean_property_elements ("classes");
+        _classes = value;
+      }
+    }
+    construct {
+      initialize ("namespace");
+      _classes = new TClass.Map ();
+      _classes.initialize_element (this);
+    }
+ }
+ public class TClass : GomElement, MappeableElement
+ {
+    [Description (nick="::name")]
+    public string name { get; set; }
+    [Description (nick="::version")]
+    public string version { get; set; }
+    [Description (nick="::c:prefix")]
+    public string prefix { get; set; }
+
+    construct {
+      initialize ("class");
+    }
+
+    public string get_map_key () { return name; }
+    public class Map : GomHashMap {
+      construct {
+        initialize (typeof (TClass));
+      }
+    }
+ }
        public static void add_tests () {
        Test.add_func ("/gxml/gom-element/read/namespace_uri", () => {
                        DomDocument doc = null;
                        try {
-                               doc = new GomDocument.from_string ("<Potions><magic:Potion 
xmlns:magic=\"http://hogwarts.co.uk/magic\"; 
xmlns:products=\"http://diagonalley.co.uk/products\"/></Potions>");
+                               doc = new GomDocument.from_string ("<Potions><magic:Potion 
xmlns:magic=\"http://hogwarts.co.uk/magic\"; xmlns:products=\"http://diagonalley.co.uk/products\";><ingredient 
products:name=\"spider\"/></magic:Potion></Potions>");
                                GXml.GomNode root = (GXml.GomNode) doc.document_element;
                                assert (root != null);
                                assert (root.node_name == "Potions");
@@ -120,6 +223,7 @@ class GomElementTest : GXmlTest  {
                                        GLib.message ("Attribute: "+k+"="+v);
                                }
 #endif
+                               message ((node as GomElement).write_string ());
                                assert ((node as DomElement).attributes.length == 2);
                                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";);
@@ -231,6 +335,77 @@ class GomElementTest : GXmlTest  {
                                assert_not_reached ();
                        }
                });
+               Test.add_func ("/gxml/gom-element/attributes/property-ns", () => {
+                       try {
+                               string str = """<Potion xmlns:c="http://c.org/1.0"; 
c:name="edumor"><ingredient c:name="spider"><child/><method c:name="move"/></ingredient></Potion>""";
+                               var p = new Potion ();
+                               assert (p.node_name == "Potion");
+                               assert (p.cname == null);
+                               assert (p.get_attribute_ns ("http://www.w3.org/2000/xmlns";, "c") == 
"http://c.org/1.0";);
+                               p.read_from_string (str);
+                               message (p.write_string ());
+                               assert (p.cname == "edumor");
+                               assert (p.ingredient != null);
+                               assert (p.ingredient.cname == "spider");
+                               assert (p.ingredient.methods != null);
+                               assert (p.ingredient.methods.length == 1);
+                               var m = p.ingredient.methods.get_item (0) as Method;
+                               assert (m.cname == "move");
+                       } catch (GLib.Error e) {
+                               GLib.message (e.message);
+                               assert_not_reached ();
+                       }
+               });
+               Test.add_func ("/gxml/gom-element/attribute-ns/collection", () => {
+                       try {
+                               string str = """<?xml version="1.0"?>
+<repository version="1.2" xmlns="http://www.gtk.org/introspection/core/1.0"; 
xmlns:c="http://www.gtk.org/introspection/c/1.0"; xmlns:glib="http://www.gtk.org/introspection/glib/1.0";>
+<include name="GXml" version="0.16"/>
+<package name="girp-0.2"/>
+<c:include name="girp.h"/>
+<namespace name="Girp" version="0.2" c:prefix="Girp">
+       <attribute name="ccode.gir-version" value="0.2"/>
+       <attribute name="ccode.cheader-filename" value="girp.h"/>
+       <attribute name="ccode.gir-namespace" value="Girp"/>
+       <class name="Repository" c:type="GirpRepository" glib:type-name="GirpRepository" 
glib:get-type="girp_repository_get_type" glib:type-struct="RepositoryClass" parent="GXml.GomElement">
+       </class>
+</namespace>
+</repository>""";
+                               var r = new Repository ();
+                               r.read_from_string (str);
+                       } catch (GLib.Error e) {
+                               GLib.message (e.message);
+                               assert_not_reached ();
+                       }
+               });
+               Test.add_func ("/gxml/gom-element/lookup-prefix", () => {
+                       try {
+                               string str = """<?xml version="1.0"?>
+<repository version="1.2" xmlns="http://www.gtk.org/introspection/core/1.0"; 
xmlns:c="http://www.gtk.org/introspection/c/1.0"; xmlns:glib="http://www.gtk.org/introspection/glib/1.0";>
+<include name="GXml" version="0.16"/>
+<package name="girp-0.2"/>
+<c:include name="girp.h"/>
+<namespace name="Girp" version="0.2" c:prefix="Girp">
+       <attribute name="ccode.gir-version" value="0.2"/>
+       <attribute name="ccode.cheader-filename" value="girp.h"/>
+       <attribute name="ccode.gir-namespace" value="Girp"/>
+       <class name="Repository" c:type="GirpRepository" glib:type-name="GirpRepository" 
glib:get-type="girp_repository_get_type" glib:type-struct="RepositoryClass" parent="GXml.GomElement">
+       </class>
+</namespace>
+</repository>""";
+                               var d = new GomDocument.from_string (str);
+                               assert (d.document_element.node_name == "repository");
+                               var lt = d.document_element.get_elements_by_tag_name ("class");
+                               assert (lt.length == 1);
+                               var n = lt[0];
+                               assert (n.node_name == "class");
+                               assert (n.lookup_namespace_uri ("c") == 
"http://www.gtk.org/introspection/c/1.0";);
+                               assert (n.lookup_prefix ("http://www.gtk.org/introspection/c/1.0";) == "c");
+                       } catch (GLib.Error e) {
+                               GLib.message (e.message);
+                               assert_not_reached ();
+                       }
+               });
                Test.add_func ("/gxml/gom-element/content/add_aside_child_nodes", () =>{
                        try {
                                var doc = new GomDocument ();
diff --git a/test/GomSerializationTest.vala b/test/GomSerializationTest.vala
index 4475dc1..debbc69 100644
--- a/test/GomSerializationTest.vala
+++ b/test/GomSerializationTest.vala
@@ -1122,10 +1122,8 @@ class GomSerializationTest : GXmlTest  {
       //assert (bs.registers == null);
       assert (bs.books != null);
       s = bs.to_string ();
-#if DEBUG
       GLib.message ("doc:"+s);
       GLib.message ("Books: "+bs.books.length.to_string ());
-#endif
       assert (bs.books.length == 3);
       assert (bs.books.nodes_index.peek_nth (0) == 0);
       assert (bs.books.nodes_index.peek_nth (1) == 1);


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