[gxml] Parser: Now use a generic DomNode



commit 9902825d80f18b19a671752871df350f8058c860
Author: Daniel Espinosa <esodan gmail com>
Date:   Fri Nov 4 12:30:16 2016 -0600

    Parser: Now use a generic DomNode
    
    Serializable is done over a node, using its
    owner document.

 gxml/GomNode.vala              |   15 ++++++---
 gxml/GomObject.vala            |    4 ++
 gxml/Parser.vala               |    7 +---
 gxml/XParser.vala              |   71 +++++++++++++++++++++------------------
 test/GomSerializationTest.vala |   12 +++++++
 5 files changed, 65 insertions(+), 44 deletions(-)
---
diff --git a/gxml/GomNode.vala b/gxml/GomNode.vala
index 6739fc2..140713c 100644
--- a/gxml/GomNode.vala
+++ b/gxml/GomNode.vala
@@ -227,23 +227,28 @@ public class GXml.GomNode : Object,
 
   public DomNode insert_before (DomNode node, DomNode? child) throws GLib.Error {
     if (!(node is GXml.GomNode))
-      throw new DomError.INVALID_NODE_TYPE_ERROR (_("Invalid attempt to add invalid node type"));
+      throw new DomError.INVALID_NODE_TYPE_ERROR
+                  (_("Invalid attempt to add invalid node type"));
     if (child != null && !this.contains (child))
-      throw new DomError.NOT_FOUND_ERROR (_("Can't find child to insert node before"));
+      throw new DomError.NOT_FOUND_ERROR
+                  (_("Can't find child to insert node before"));
     if (!(this is DomDocument
           || this is DomElement
           || this is DomDocumentFragment))
-      throw new DomError.HIERARCHY_REQUEST_ERROR (_("Invalid attempt to insert a node"));
+      throw new DomError.HIERARCHY_REQUEST_ERROR
+                  (_("Invalid attempt to insert a node"));
     if (!(node is DomDocumentFragment
           || node is DomDocumentType
           || node is DomElement
           || node is DomText
           || node is DomProcessingInstruction
           || node is DomComment))
-      throw new DomError.HIERARCHY_REQUEST_ERROR (_("Invalid attempt to insert an invalid node type"));
+      throw new DomError.HIERARCHY_REQUEST_ERROR
+                  (_("Invalid attempt to insert an invalid node type"));
     if ((node is DomText && this is DomDocument)
           || (node is DomDocumentType && !(this is DomDocument)))
-      throw new DomError.HIERARCHY_REQUEST_ERROR (_("Invalid attempt to insert a document's type or text 
node to a invalid parent"));
+      throw new DomError.HIERARCHY_REQUEST_ERROR
+                  (_("Invalid attempt to insert a document's type or text node to a invalid parent"));
     //FIXME: We should follow steps for DOM4 observers in https://www.w3.org/TR/dom/#concept-node-pre-insert
     if (child != null) {
       int i = this.child_nodes.index_of (child as GXml.DomNode);
diff --git a/gxml/GomObject.vala b/gxml/GomObject.vala
index 18abfc1..e34302c 100644
--- a/gxml/GomObject.vala
+++ b/gxml/GomObject.vala
@@ -153,6 +153,10 @@ public interface GXml.GomObject : GLib.Object,
     }
     return null;
   }
+  /**
+   * Search for a property and set it to null if possible, if value can't
+   * be removed, returns without change.
+   */
   public virtual bool remove_attribute (string name) {
     var prop = get_class ().find_property (name);
     if (prop != null) {
diff --git a/gxml/Parser.vala b/gxml/Parser.vala
index fc968d8..a6c8b48 100644
--- a/gxml/Parser.vala
+++ b/gxml/Parser.vala
@@ -43,7 +43,7 @@ public interface GXml.Parser : Object {
   /**
    * A {@link GXml.DomDocument} to read to or write from
    */
-  public abstract DomDocument document { get; }
+  public abstract DomNode node { get; }
   /**
    * Writes a {@link GXml.DomDocument} to a {@link GLib.File}
    */
@@ -84,9 +84,4 @@ public interface GXml.Parser : Object {
    */
   public abstract void read_string (string str,
                                    GLib.Cancellable? cancellable) throws GLib.Error;
-  /**
-   * From data stream read until a node is found. You should check its type
-   * using {@link current_type}
-   */
-  public abstract bool read_node (DomNode node) throws GLib.Error;
 }
diff --git a/gxml/XParser.vala b/gxml/XParser.vala
index a6609e7..1fca471 100644
--- a/gxml/XParser.vala
+++ b/gxml/XParser.vala
@@ -27,16 +27,23 @@ using Xml;
  */
 public class GXml.XParser : Object, GXml.Parser {
   private DomDocument _document;
+  private DomNode _node;
   private TextReader tr;
   private Xml.TextWriter tw;
 
   public bool backup { get; set; }
   public bool indent { get; set; }
 
-  public DomDocument document { get { return _document; } }
+  public DomNode node { get { return _node; } }
 
 
-  public XParser (DomDocument doc) { _document = doc; }
+  public XParser (DomNode node) {
+    _node = node;
+    if (_node is DomDocument)
+      _document = _node as DomDocument;
+    else
+      _document = _node.owner_document;
+  }
 
   construct {
     backup = true;
@@ -47,17 +54,17 @@ public class GXml.XParser : Object, GXml.Parser {
                             GLib.Cancellable? cancellable) throws GLib.Error {
     var buf = new Xml.Buffer ();
     tw = Xmlx.new_text_writer_memory (buf, 0);
-    tw.start_document ();
+    if (_node is DomDocument) tw.start_document ();
     tw.set_indent (indent);
     // Root
-    if (_document.document_element == null) {
-      tw.end_document ();
+    if (_node is DomDocument) {
+      if ((_node as DomDocument).document_element == null)
+        tw.end_document ();
     }
-    var dns = new ArrayList<string> ();
 #if DEBUG
     GLib.message ("Starting writting Document child nodes");
 #endif
-    start_node (_document);
+    start_node (_node);
 #if DEBUG
     GLib.message ("Ending writting Document child nodes");
 #endif
@@ -94,17 +101,12 @@ public class GXml.XParser : Object, GXml.Parser {
     GLib.message ("DATA:"+(string)b.data);
 #endif
     tr = new TextReader.for_memory ((char[]) b.data, (int) b.get_data_size (), "/gxml_memory");
-    while (read_node (_document));
+    while (read_current_node (_node, true));
   }
 
-
-  /**
-   * Parse current node in {@link Xml.TextReader}.
-   *
-   * Returns: a {@link GXml.Node} respresenting current parsed one.
-   */
-  public bool read_node (DomNode node) throws GLib.Error {
-    GXml.DomNode n = null;
+  public bool read_current_node (DomNode node, bool read_current = false)
+                                throws GLib.Error {
+    GXml.DomNode n = node;
     string prefix = null, nsuri = null;
 #if DEBUG
     GLib.message ("ReadNode: Current Node:"+node.node_name);
@@ -129,18 +131,20 @@ public class GXml.XParser : Object, GXml.Parser {
       break;
     case Xml.ReaderType.ELEMENT:
       bool isempty = (tr.is_empty_element () == 1);
-#if DEBUG
-      if (isempty) GLib.message ("Is Empty node:"+node.node_name);
-      GLib.message ("ReadNode: Element: "+tr.const_local_name ());
-#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 ());
-      } else
-        n = _document.create_element (tr.const_local_name ());
-      node.append_child (n);
+      if (node is DomDocument || !read_current) {
+#if DEBUG
+        if (isempty) GLib.message ("Is Empty node:"+node.node_name);
+        GLib.message ("ReadNode: Element: "+tr.const_local_name ());
+#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 ());
+        } else
+          n = _document.create_element (tr.const_local_name ());
+        node.append_child (n);
+      }
       var nattr = tr.attribute_count ();
 #if DEBUG
       GLib.message ("Number of Attributes:"+nattr.to_string ());
@@ -195,7 +199,7 @@ public class GXml.XParser : Object, GXml.Parser {
         }
       }
       if (isempty) return true;
-      while (read_node (n) == true);
+      while (read_current_node (n) == true);
 #if DEBUG
       //GLib.message ("Current Document: "+node.document.to_string ());
 #endif
@@ -302,17 +306,18 @@ public class GXml.XParser : Object, GXml.Parser {
     int size;
     Xml.Doc doc = new Xml.Doc ();
     tw = Xmlx.new_text_writer_doc (ref doc);
-    tw.start_document ();
+    if (_node is DomDocument) tw.start_document ();
     tw.set_indent (indent);
     // Root
-    if (_document.document_element == null) {
-      tw.end_document ();
+    if (_node is DomDocument) {
+      if ((node as DomDocument).document_element == null) {
+        tw.end_document ();
+      }
     }
-    var dns = new ArrayList<string> ();
 #if DEBUG
     GLib.message ("Starting writting Document child nodes");
 #endif
-    start_node (_document);
+    start_node (_node);
 #if DEBUG
     GLib.message ("Ending writting Document child nodes");
 #endif
@@ -331,7 +336,7 @@ public class GXml.XParser : Object, GXml.Parser {
   private void start_node (GXml.DomNode node)
     throws GLib.Error
   {
-    GLib.message ("Starting node...");
+    GLib.message ("Starting node..."+node.node_name);
     int size = 0;
 #if DEBUG
     GLib.message (@"Starting Node: start Node: '$(node.node_name)'");
diff --git a/test/GomSerializationTest.vala b/test/GomSerializationTest.vala
index 52b7f6b..ec216ae 100644
--- a/test/GomSerializationTest.vala
+++ b/test/GomSerializationTest.vala
@@ -98,5 +98,17 @@ class GomSerializationTest : GXmlTest  {
       s = t.to_string ();
       GLib.message ("DOC:"+s);
     });
+    Test.add_func ("/gxml/gom-serialization/read/properties", () => {
+      /*var b = new Book ();
+      (b.owner_document as GomDocument)
+        .parser.read_string ("<book name=\"Loco\"/>", null);
+      string s = (b.owner_document as GomDocument).to_string ();
+      assert (s != null);
+      assert ("<Book Name=\"Loco\"/>" in s);
+      b.name = "My Book";
+      assert (b.get_attribute ("name") == "My Book");
+      s = b.to_string ();
+      assert ("<Book Name=\"My Book\"/>" in s);*/
+    });
   }
 }


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