[gxml] GomElement: Fixed namespace implementation



commit e7938f1320c908a1e39d86810e419b5a1135417c
Author: Daniel Espinosa <esodan gmail com>
Date:   Tue Nov 1 00:01:50 2016 -0600

    GomElement: Fixed namespace implementation
    
    Much more error messages and API changes to improve errors
    on namespaces.
    
    Setting an attribute with namespace make namespaced elements
    taking, if not already, given namespace and checking if
    no conflics exists with some other already defined.

 NEWS                      |    1 +
 gxml/DomElement.vala      |    4 +-
 gxml/GXmlElement.vala     |    4 +-
 gxml/GomElement.vala      |  118 ++++++++++++++++++++++++++++-----------------
 gxml/GomText.vala         |    1 -
 test/GomDocumentTest.vala |   12 ++--
 6 files changed, 84 insertions(+), 56 deletions(-)
---
diff --git a/NEWS b/NEWS
index dc6ccba..af84466 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ Version 0.13.0
 * API change changed long/ulong to int
 * Added new DOM4 implementation called GOM
 * API change GXml.NodeType changed X_UNKNOWN to INVALID
+* API change fixed DomElement.set_attribute/_ns now requires not null values
 
 ===============
 Version 0.12.0
diff --git a/gxml/DomElement.vala b/gxml/DomElement.vala
index f28da7b..c10c5ad 100644
--- a/gxml/DomElement.vala
+++ b/gxml/DomElement.vala
@@ -45,8 +45,8 @@ public interface GXml.DomElement : GLib.Object,
 
   public abstract string? get_attribute (string name);
   public abstract string? get_attribute_ns (string? namespace, string local_name);
-  public abstract void set_attribute (string name, string? value);
-  public abstract void set_attribute_ns (string? namespace, string name, string? value);
+  public abstract void set_attribute (string name, string value) throws GLib.Error;
+  public abstract void set_attribute_ns (string? namespace, string name, string value) throws GLib.Error;
   public abstract void remove_attribute (string name);
   public abstract void remove_attribute_ns (string? namespace, string local_name);
   public abstract bool has_attribute (string name);
diff --git a/gxml/GXmlElement.vala b/gxml/GXmlElement.vala
index 8d8a3f2..a06c13e 100644
--- a/gxml/GXmlElement.vala
+++ b/gxml/GXmlElement.vala
@@ -223,8 +223,8 @@ public class GXml.GElement : GXml.GNonDocumentChildNode,
     if (p == null) return null;
     return p.value;
   }
-  public void set_attribute (string name, string? value) { set_attr (name, value); }
-  public void set_attribute_ns (string? namespace, string name, string? value) {
+  public void set_attribute (string name, string value) throws GLib.Error { set_attr (name, value); }
+  public void set_attribute_ns (string? namespace, string name, string value) throws GLib.Error {
     set_ns_attr (namespace, name, value);
   }
   public void remove_attribute (string name) {
diff --git a/gxml/GomElement.vala b/gxml/GomElement.vala
index 8a6452d..4926057 100644
--- a/gxml/GomElement.vala
+++ b/gxml/GomElement.vala
@@ -156,7 +156,6 @@ public class GXml.GomElement : GomNode,
     }
   }
 
-
   construct {
     _node_type = DomNode.NodeType.ELEMENT_NODE;
     _attributes = new Attributes (this);
@@ -167,11 +166,13 @@ public class GXml.GomElement : GomNode,
     _document = doc;
     _local_name = local_name;
   }
-  public GomElement.namespace (DomDocument doc, string namespace, string prefix, string local_name) {
+  public GomElement.namespace (DomDocument doc, string? namespace_uri,
+                              string? prefix, string local_name) {
     _document = doc;
     _local_name = local_name;
-    _namespace_uri = namespace;
-    _prefix = prefix;
+    var a = new GomAttr.namespace (this, "http://www.w3.org/2000/xmlns/";,
+                                  prefix, "xmlns", namespace_uri);
+    _attributes.set_named_item_ns (a);
   }
   /**
    * Holds attributes in current node, using attribute's name as key
@@ -245,28 +246,50 @@ public class GXml.GomElement : GomNode,
         throw new DomError.INVALID_CHARACTER_ERROR (_("Invalid attribute name"));
       if (!(node is DomAttr))
         throw new DomError.HIERARCHY_REQUEST_ERROR (_("Invalid node type. DomAttr was expected"));
-      string n = (node as DomAttr).local_name;
-      string ns = (node as DomAttr).namespace_uri;
-      string v = node.node_value;
-      if ((node as DomAttr).prefix == null
-          && (node as DomAttr).local_name.down () != "xmlns") {
-        set ("xmlns","http://www.w3.org/2000/xmlns/";);
-        return new GomAttr (_element, "xmlns", "http://www.w3.org/2000/xmlns/";);
-      }
-      if ((node as DomAttr).prefix == null
-          || (node as DomAttr).prefix == "") {
-        set ((node as DomAttr).local_name, node.node_value);
-        return new GomAttr (_element, node.node_name, node.node_value);
+      if (((node as DomAttr).prefix == null || (node as DomAttr).prefix == "")
+          && node.node_name != "xmlns")
+        throw new DomError.NAMESPACE_ERROR (_("Invalid namespaced attribute's name and prefix"));
+      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";)
+        throw new DomError.NAMESPACE_ERROR (_("Namespace attributes prefixed with xmlns should use a 
namespace uri http://www.w3.org/2000/xmlns";));
+      if ((node as DomAttr).prefix == ""
+          || (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 = null;
+      if ((node as DomAttr).prefix == "xmlns")
+        nsp = _element.lookup_prefix (node.node_value);
+      if ((node as DomAttr).prefix != "xmlns")
+        nsp = _element.lookup_prefix ((node as DomAttr).namespace_uri);
+      if (nsp != null)
+        GLib.message ("Found PREFIX: "+nsp+" Node prefix: "+(node as DomAttr).prefix+"Node Value: 
"+node.node_value);
+      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;
+        throw new DomError.NAMESPACE_ERROR (_("Attribute's prefix and namespace URI conflics with already 
defined namespace%s").printf (snsp));
       }
-      string p = null;
-      if ((node as DomAttr).prefix != ""
-          && (node as DomAttr).prefix != null) p = (node as DomAttr).prefix;
-      set (p+":"+(node as DomAttr).local_name, node.node_value);
-      if ((node as DomAttr).prefix.down () == "xmlns"
-          || (node as DomAttr).local_name == "xmlns")
-        ns = node.node_value;
-      return new GomAttr.namespace (_element,
-                                    ns, p, n, node.node_value);
+      string p = "";
+      if ((node as DomAttr).prefix != null) p = (node as DomAttr).prefix + ":";
+      set (p+(node as DomAttr).local_name,
+          node.node_value);
+      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;
     }
   }
   public DomNamedNodeMap attributes { owned get { return (DomNamedNodeMap) _attributes; } }
@@ -288,43 +311,48 @@ public class GXml.GomElement : GomNode,
     if (p == null) return null;
     return p.node_value;
   }
-  public void set_attribute (string name, string? value) {
+  public void set_attribute (string name, string value) throws GLib.Error {
     bool res = (this as GomObject).set_attribute (name, value);
     if (res) return;
     var a = new GomAttr (this, name, value);
     attributes.set_named_item (a);
   }
-  public void set_attribute_ns (string? namespace_uri, string name, string? value) {
+  public void set_attribute_ns (string? namespace_uri,
+                                string name, string value) throws GLib.Error {
     string p = "";
     string n = name;
     if (":" in name) {
       var s = name.split (":");
-      if (s.length != 2) return;
+      if (s.length != 2)
+        throw new DomError.NAMESPACE_ERROR (_("Invalid attribute name. Just one prefix is allowed"));
       p = s[0];
       n = s[1];
     } else
       n = name;
-    if (p == "xml" && namespace_uri != "http://www.w3.org/2000/xmlns/";) {
-      GLib.warning (_("Invalid namespace. If prefix is xml name space uri shoud be 
http://www.w3.org/2000/xmlns/";));
-      return;
-    }
-    if (p == "xmlns" && namespace_uri != "http://www.w3.org/2000/xmlns/";) {
-      GLib.warning (_("Invalid namespace. If attribute's name is xmlns name space uri shoud be 
http://www.w3.org/2000/xmlns/";));
-      return;
-    }
-    // Check a namespace is set
-    if (_prefix == null && _namespace_uri == null)
-      if (p.down () == "xmlns"
-          || n == "xmlns")
-      {
-        if (p != "")
-          _prefix = p;
-        _namespace_uri = namespace_uri;
+    if (namespace_uri == null && p == "")
+       throw new DomError.NAMESPACE_ERROR (_("Invalid namespace. If prefix is null, name space uri shoud not 
be null"));
+    if (p == "xml" && namespace_uri != "http://www.w3.org/2000/xmlns/";)
+       throw new DomError.NAMESPACE_ERROR (_("Invalid namespace. If prefix is xml name space uri shoud be 
http://www.w3.org/2000/xmlns/";));
+    if (p == "xmlns" && namespace_uri != "http://www.w3.org/2000/xmlns/";)
+       throw new DomError.NAMESPACE_ERROR (_("Invalid namespace. If attribute's name is xmlns name space uri 
shoud be http://www.w3.org/2000/xmlns/";));
+    if (p == "" && n != "xmlns")
+      throw new DomError.NAMESPACE_ERROR (_("Invalid attribute name. No prefixed attributes should use xmlns 
name"));
+    // Check if a namespace is set
+    if (_prefix == null && _namespace_uri == null) {
+      GLib.message ("Setting NS:"+p+":"+n+":"+namespace_uri+":"+value);
+      if (p == "xmlns" &&
+          (namespace_uri == "http://www.w3.org/2000/xmlns/";
+           || namespace_uri == "http://www.w3.org/2000/xmlns";)) {
+        _prefix = n;
+        _namespace_uri = value;
       }
+      if (n == "xmlns" && p == "")
+        _namespace_uri = value;
+    }
     var a = new GomAttr.namespace (this, namespace_uri, p, n, value);
     try { _attributes.set_named_item_ns (a); }
     catch (GLib.Error e) {
-      GLib.message (_("Setting namespaced property error: ")+e.message);
+      throw new DomError.NAMESPACE_ERROR (_("Setting namespaced property error: ")+e.message);
     }
   }
   public void remove_attribute (string name) {
diff --git a/gxml/GomText.vala b/gxml/GomText.vala
index 91987ac..b533f85 100644
--- a/gxml/GomText.vala
+++ b/gxml/GomText.vala
@@ -93,7 +93,6 @@ public class GXml.GomProcessingInstruction : GomCharacterData,
   public GomProcessingInstruction (DomDocument doc, string target, string data) {
     _document = doc;
     _node_value = data;
-    GLib.message ("PI: Initialized");
     _local_name = target;
   }
 }
diff --git a/test/GomDocumentTest.vala b/test/GomDocumentTest.vala
index a166904..b30e966 100644
--- a/test/GomDocumentTest.vala
+++ b/test/GomDocumentTest.vala
@@ -300,22 +300,22 @@ class GomDocumentTest : GXmlTest {
                Test.add_func ("/gxml/gom-document/namespace", () => {
                        try {
                                DomDocument doc = new GomDocument.from_string 
("<document_element><child/></document_element>");
-                               doc.document_element.set_attribute_ns 
("http://www.gnome.org/GXml","xmlns:gxml","http://www.gnome.org/GXml";);
+                               doc.document_element.set_attribute_ns ("http://www.w3.org/2000/xmlns/";,
+                                                                                                             
                                                                          
"xmlns","http://www.gnome.org/GXml";);
                                assert (doc.document_element != null);
                                assert (doc.document_element.namespace_uri != null);
                                assert (doc.document_element.namespace_uri == "http://www.gnome.org/GXml";);
-                               assert (doc.document_element.prefix != null);
-                               assert (doc.document_element.prefix == "gxml");
+                               assert (doc.document_element.prefix == null);
                                assert (doc.document_element.child_nodes != null);
                                assert (doc.document_element.child_nodes.size == 1);
                                var c = doc.document_element.child_nodes[0] as DomElement;
                                assert (c is DomElement);
-                               c.set_attribute_ns ("http://www.gnome.org/GXml2","gxml2";, 
"http://www.gnome.org/GXml2";);
+                               c.set_attribute_ns ("http://www.w3.org/2000/xmlns/","xmlns:gxml2";, 
"http://www.gnome.org/GXml2";);
                                assert (c.prefix == "gxml2");
                                assert (c.namespace_uri == "http://www.gnome.org/GXml2";);
-                               c.set_attribute_ns ("http://www.gnome.org/GXml2","gxml:prop","val";);
+                               c.set_attribute_ns ("http://www.gnome.org/GXml2","gxml2:prop","val";);
                                var p = (c as DomElement).get_attribute_ns ("http://www.gnome.org/GXml2";, 
"prop");
-                               assert (p == null);
+                               assert (p != null);
                                assert (p == "val");
                        } catch (GLib.Error e) {
                                GLib.message ("ERROR: "+ e.message);


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