[gxml] GOM: Fixed adding namespaced elements



commit a25267b2cb3139f3d9b470344c9c47f9b9d2ce99
Author: Daniel Espinosa <esodan gmail com>
Date:   Thu Nov 3 10:46:30 2016 -0600

    GOM: Fixed adding namespaced elements
    
    Namespaced elements should have a valid
    namespace according with the ones defined
    in parent node to add to.
    
    If a namespaced element have a defined
    URI, namespace is not found in parent node
    to add to and no namespace attribute is
    defined in element, one is added using
    element's prefix and namespace URI

 gxml/GomDocument.vala     |    6 ++++--
 gxml/GomElement.vala      |    3 ---
 gxml/GomNode.vala         |   28 +++++++++++++++++++++++++++-
 test/GomDocumentTest.vala |   34 +++++++++++++++++++++++++++++++++-
 4 files changed, 64 insertions(+), 7 deletions(-)
---
diff --git a/gxml/GomDocument.vala b/gxml/GomDocument.vala
index e700d0d..d14e088 100644
--- a/gxml/GomDocument.vala
+++ b/gxml/GomDocument.vala
@@ -117,13 +117,15 @@ public class GXml.GomDocument : GomNode,
     if (":" in qualified_name) {
       var s = qualified_name.split (":");
       if (s.length != 2)
-        throw new DomError.NAMESPACE_ERROR (_("Invalid node name"));
+        throw new DomError.NAMESPACE_ERROR
+          (_("Creating an namespaced element with invalid node name"));
       nsp = s[0];
       n = s[1];
     } else
       n = qualified_name;
     if (nsp == "" && ns == null)
-      throw new DomError.NAMESPACE_ERROR (_("Invalid namespace"));
+      throw new DomError.NAMESPACE_ERROR
+        (_("Creating an namespaced element with invalid namespace"));
       // TODO: check for xmlns https://www.w3.org/TR/dom/#dom-document-createelementns
     return new GomElement.namespace (this, ns, nsp, n);
   }
diff --git a/gxml/GomElement.vala b/gxml/GomElement.vala
index b64e8b8..9dcac24 100644
--- a/gxml/GomElement.vala
+++ b/gxml/GomElement.vala
@@ -182,9 +182,6 @@ public class GXml.GomElement : GomNode,
     _local_name = local_name;
     _namespace_uri = namespace_uri;
     _prefix = prefix;
-    var a = new GomAttr.namespace (this, "http://www.w3.org/2000/xmlns/";,
-                                  "xmlns", prefix, namespace_uri);
-    _attributes.set_named_item_ns (a);
   }
   /**
    * Holds attributes in current node, using attribute's name as key
diff --git a/gxml/GomNode.vala b/gxml/GomNode.vala
index fe307d6..8b8bceb 100644
--- a/gxml/GomNode.vala
+++ b/gxml/GomNode.vala
@@ -204,7 +204,33 @@ public class GXml.GomNode : Object,
     return false;
   }
 
-  internal void set_parent (DomNode node) {
+  internal void set_parent (DomNode node) throws GLib.Error {
+    if (this is DomElement) {
+      var e = (this as DomElement);
+      if (e.namespace_uri != null || e.prefix != null) {
+        string nsprefix = node.lookup_prefix (e.namespace_uri);
+        string nsuri = node.lookup_namespace_uri (e.prefix);
+        if (nsprefix == null && nsuri == null
+            && e.namespace_uri != null) {
+          string name = "xmlns";
+          if (e.prefix != null)
+            name = name + e.prefix;
+          if (e.get_attribute_ns (e.namespace_uri, e.prefix) == null)
+            e.set_attribute_ns ("http://www.w3.org/2000/xmlns/";,
+                              name, e.namespace_uri);
+        }
+        if (nsprefix != null && nsprefix != e.prefix) {
+          throw new DomError.NAMESPACE_ERROR
+            (_("Trying to add a namespaced element to a parent with invalid prefix for namesapce %s ")
+              .printf (e.namespace_uri));
+        }
+        if (nsuri != null && nsuri != e.namespace_uri) {
+          throw new DomError.NAMESPACE_ERROR
+            (_("Trying to add a namespaced element to a parent with invalid uri for prefix %s ")
+              .printf (e.prefix));
+        }
+      }
+    }
     _parent = node;
   }
 
diff --git a/test/GomDocumentTest.vala b/test/GomDocumentTest.vala
index de1c1ca..c456f73 100644
--- a/test/GomDocumentTest.vala
+++ b/test/GomDocumentTest.vala
@@ -92,7 +92,39 @@ class GomDocumentTest : GXmlTest {
                                assert_not_reached ();
                        }
                        });
-               Test.add_func ("/gxml/gom-document/gfile/remote", () => {
+               Test.add_func ("/gxml/gom-document/gfile/remote/read", () => {
+                       try {
+                               var rf = GLib.File.new_for_uri 
("https://git.gnome.org/browse/gxml/plain/gxml.doap";);
+                               if (!rf.query_exists ()) {
+                                       GLib.message ("No remote file available. Skiping...");
+                                       return;
+                               }
+                               var d = new GomDocument.from_file (rf);
+                               assert (d != null);
+                               assert (d.document_element != null);
+                               assert (d.document_element.node_name == "Project");
+                               bool fname, fshordesc, fdescription, fhomepage;
+                               fname = fshordesc = fdescription = fhomepage = false;
+                               foreach (DomNode n in d.document_element.child_nodes) {
+                                       if (n.node_name == "name") fname = true;
+                                       if (n.node_name == "shortdesc") fshordesc = true;
+                                       if (n.node_name == "description") fdescription = true;
+                                       if (n.node_name == "homepage") fhomepage = true;
+                               }
+                               assert (fname);
+                               assert (fshordesc);
+                               assert (fdescription);
+                               assert (fhomepage);
+                               var f = GLib.File.new_for_path (GXmlTestConfig.TEST_SAVE_DIR+"/xml.doap");
+                               d.write_file (f);
+                               assert (f.query_exists ());
+                               f.delete ();
+                       } catch (GLib.Error e) {
+                               GLib.message ("Error: "+e.message);
+                               assert_not_reached ();
+                       }
+               });
+               Test.add_func ("/gxml/gom-document/gfile/remote/write", () => {
                        try {
                                var rf = GLib.File.new_for_uri 
("https://git.gnome.org/browse/gxml/plain/gxml.doap";);
                                if (!rf.query_exists ()) {


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