[gxml] New libxml2 implementation under GXml.GNode derived classes



commit e0d35e8488b7068f6ece5c0d4cdd0e436e58ced7
Author: Daniel Espinosa <esodan gmail com>
Date:   Thu Jan 28 14:33:01 2016 -0600

    New libxml2 implementation under GXml.GNode derived classes
    
    * API changes, by changing most properties to be owned in order
      to make room for libxml2 pointer management not in GXml classes
    
    * New GXml.GNode derived classes using libxml2 pointers internally
      equivalent on GXml.xNode, but simplier and with no support, jet,
      for DOM API

 gxml/Attribute.vala                    |    5 +-
 gxml/CDATA.vala                        |    2 +-
 gxml/Comment.vala                      |    2 +-
 gxml/Document.vala                     |    2 +-
 gxml/Element.vala                      |    2 +-
 gxml/GXmlAttribute.vala                |   52 ++++
 gxml/GXmlCDATA.vala                    |   35 +++
 gxml/GXmlComment.vala                  |   35 +++
 gxml/GXmlDocument.vala                 |  407 ++++++++++++++++++++++++++++++++
 gxml/GXmlElement.vala                  |   57 +++++
 gxml/GXmlHashMapAttr.vala              |  175 ++++++++++++++
 gxml/GXmlListChildren.vala             |  237 +++++++++++++++++++
 gxml/GXmlListNamespaces.vala           |  150 ++++++++++++
 gxml/GXmlNamespace.vala                |   45 ++++
 gxml/GXmlNode.vala                     |  115 +++++++++
 gxml/GXmlProcessingInstruction.vala    |   36 +++
 gxml/GXmlText.vala                     |   35 +++
 gxml/Makefile.am                       |   14 +-
 gxml/Namespace.vala                    |    4 +-
 gxml/Node.vala                         |   18 +-
 gxml/ProcessingInstruction.vala        |    4 +-
 gxml/Serializable.vala                 |    4 +-
 gxml/SerializableGeeArrayList.vala     |    8 +-
 gxml/SerializableGeeDualKeyMap.vala    |    8 +-
 gxml/SerializableGeeHashMap.vala       |    8 +-
 gxml/SerializableGeeTreeMap.vala       |    8 +-
 gxml/SerializableJson.vala             |    8 +-
 gxml/SerializableObjectModel.vala      |    4 +-
 gxml/Text.vala                         |    2 +-
 gxml/TwAttribute.vala                  |   15 +-
 gxml/TwCDATA.vala                      |    4 +-
 gxml/TwComment.vala                    |    4 +-
 gxml/TwDocument.vala                   |    2 +-
 gxml/TwElement.vala                    |    8 +-
 gxml/TwNamespace.vala                  |    4 +-
 gxml/TwNode.vala                       |   12 +-
 gxml/TwProcessingInstruction.vala      |    6 +-
 gxml/TwText.vala                       |    4 +-
 gxml/libxml-Attr.vala                  |   30 ++-
 gxml/libxml-Comment.vala               |    2 +-
 gxml/libxml-Document.vala              |    5 +-
 gxml/libxml-DocumentType.vala          |    4 +-
 gxml/libxml-Element.vala               |    4 +-
 gxml/libxml-NamespaceAttr.vala         |    8 +-
 gxml/libxml-Node.vala                  |   10 +-
 gxml/libxml-ProcessingInstruction.vala |   10 +-
 gxml/libxml-Text.vala                  |    2 +-
 47 files changed, 1526 insertions(+), 90 deletions(-)
---
diff --git a/gxml/Attribute.vala b/gxml/Attribute.vala
index 3bea24e..f3678cb 100644
--- a/gxml/Attribute.vala
+++ b/gxml/Attribute.vala
@@ -30,5 +30,8 @@ using Gee;
  * Attribute's name could be get from { link GXml.Node.name} property. Its value
  * should be get from { link GXml.Node.value} property.
  */
-public interface GXml.Attribute : Object, GXml.Node {}
+public interface GXml.Attribute : Object, GXml.Node {
+  public abstract Namespace @namespace { owned get; set; }
+  public abstract string prefix { owned get; }
+}
 
diff --git a/gxml/CDATA.vala b/gxml/CDATA.vala
index 264abc2..e555a0d 100644
--- a/gxml/CDATA.vala
+++ b/gxml/CDATA.vala
@@ -31,5 +31,5 @@ public interface GXml.CDATA : Object, GXml.Node
   /**
    * This should be implemented by returning { link GXml.Node.value}
    */
-  public abstract string str { get; }
+  public abstract string str { owned get; }
 }
diff --git a/gxml/Comment.vala b/gxml/Comment.vala
index 90b2dd9..6a073dd 100644
--- a/gxml/Comment.vala
+++ b/gxml/Comment.vala
@@ -29,6 +29,6 @@ public interface GXml.Comment : Object, GXml.Node
   /**
    * This should be implemented by returning { link GXml.Node.value}
    */
-  public abstract string str { get; }
+  public abstract string str { owned get; }
 }
 
diff --git a/gxml/Document.vala b/gxml/Document.vala
index 41b51e3..2141b73 100644
--- a/gxml/Document.vala
+++ b/gxml/Document.vala
@@ -62,7 +62,7 @@ public interface GXml.Document : Object, GXml.Node
   /**
    * XML document root node as a { link GXml.Element}.
    */
-  public abstract GXml.Node root { get; }
+  public abstract GXml.Node root { owned get; }
   /**
    * Stores a { link GLib.File} to save/read XML documents to/from.
    */
diff --git a/gxml/Element.vala b/gxml/Element.vala
index 7ce9cd3..8d7f5f7 100644
--- a/gxml/Element.vala
+++ b/gxml/Element.vala
@@ -59,7 +59,7 @@ public interface GXml.Element : Object, GXml.Node
     /**
      * This should be just a different name for { link GXml.Node.name}.
      */
-    public abstract string tag_name { get; }
+    public abstract string tag_name { owned get; }
     /**
      * This should be just a different name for { link GXml.Node.value}.
      */
diff --git a/gxml/GXmlAttribute.vala b/gxml/GXmlAttribute.vala
new file mode 100644
index 0000000..5895e60
--- /dev/null
+++ b/gxml/GXmlAttribute.vala
@@ -0,0 +1,52 @@
+/* GAttribute.vala
+ *
+ * Copyright (C) 2016  Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *      Daniel Espinosa <esodan gmail com>
+ */
+
+using Gee;
+
+/**
+ * Class implemeting { link GXml.Attribute} interface, not tied to libxml-2.0 library.
+ */
+public class GXml.GAttribute : GXml.GNode, GXml.Attribute
+{
+  private Xml.Attr* _attr;
+  public GAttribute (Xml.Attr *node)
+  {
+    _attr = node;
+    _node = _attr->parent;
+  }
+  public Namespace @namespace {
+    owned get {
+      if (_attr == null) return null;
+      if (_attr->ns == null) return null;
+      return new GNamespace (_attr->ns);
+    }
+    set {
+      
+    }
+  }
+  public string prefix {
+    owned get {
+      if (_attr == null) return "";
+      if (_attr->ns == null) return "";
+      return _attr->ns->prefix.dup ();
+    }
+  }
+}
diff --git a/gxml/GXmlCDATA.vala b/gxml/GXmlCDATA.vala
new file mode 100644
index 0000000..7d91061
--- /dev/null
+++ b/gxml/GXmlCDATA.vala
@@ -0,0 +1,35 @@
+/* GXmlCDATA.vala
+ *
+ * Copyright (C) 2016  Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *      Daniel Espinosa <esodan gmail com>
+ */
+
+using Gee;
+
+/**
+ * Class implemeting { link GXml.CDATA} interface, not tied to libxml-2.0 library.
+ */
+public class GXml.GCDATA : GXml.GNode, GXml.CDATA
+{
+  public GCDATA (Xml.Node *node)
+  {
+    _node = node;
+  }
+  // GXml.CDATA
+  public string str { owned get { return base.value; } }
+}
diff --git a/gxml/GXmlComment.vala b/gxml/GXmlComment.vala
new file mode 100644
index 0000000..2927b6e
--- /dev/null
+++ b/gxml/GXmlComment.vala
@@ -0,0 +1,35 @@
+/* GXmlComment.vala
+ *
+ * Copyright (C) 2016  Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *      Daniel Espinosa <esodan gmail com>
+ */
+
+using Gee;
+
+/**
+ * Class implemeting { link GXml.Comment} interface, not tied to libxml-2.0 library.
+ */
+public class GXml.GComment : GXml.GNode, GXml.Comment
+{
+  public GComment (Xml.Node *node)
+  {
+    _node = node;
+  }
+  // GXml.Comment
+  public string str { owned get { return base.value; } }
+}
diff --git a/gxml/GXmlDocument.vala b/gxml/GXmlDocument.vala
new file mode 100644
index 0000000..239d38e
--- /dev/null
+++ b/gxml/GXmlDocument.vala
@@ -0,0 +1,407 @@
+/* GHtmlDocument.vala
+ *
+ * Copyright (C) 2016  Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *      Daniel Espinosa <esodan gmail com>
+ */
+
+using Gee;
+using Xml;
+
+/**
+ * Class implemeting { link GXml.Document} interface, not tied to libxml-2.0 library.
+ *
+ * This class use { link Xml.TextWriter} to write down XML documents using
+ * its contained { link GXml.Node} childs or other XML structures.
+ */
+public class GXml.GDocument : GXml.GNode, GXml.Document
+{
+  protected Xml.Doc* doc;
+  protected Xml.Buffer _buffer;
+
+  public GDocument () {
+    doc = new Xml.Doc ();
+  }
+  public GDocument.from_path (string path, int options = 0) throws GLib.Error {
+    this.from_file (File.new_for_path (path), options);
+  }
+
+  public GDocument.from_uri (string uri, int options = 0) throws GLib.Error {
+    this.from_file (File.new_for_uri (uri), options);
+  }
+
+  public GDocument.from_file (GLib.File file, int options = 0, Cancellable? cancel = null) throws GLib.Error 
{
+    if (!file.query_exists ())
+      throw new DocumentError.INVALID_DOCUMENT_ERROR (_("File doesn't exists"));
+    var b = new MemoryOutputStream.resizable ();
+    b.splice (file.read (), 0);
+    this.from_string ((string) b.data, options);
+  }
+
+  public GDocument.from_string (string str, int options = 0) {
+    Xmlx.reset_last_error ();
+    doc = Xml.Parser.parse_memory (str, (int) str.length);
+    if (doc == null)
+      doc = new Xml.Doc ();
+  }
+  public GDocument.from_doc (Xml.Doc doc) { this.doc = doc; }
+  // GXml.Node
+  public override bool set_namespace (string uri, string? prefix)
+  {
+    var root = doc->get_root_element ();
+    if (root != null) {
+      var ns = root->new_ns (uri, prefix);
+      return (ns != null);
+    }
+    return false;
+  }
+  public override GXml.Document document { get { return this; } }
+  // GXml.Document
+  public bool indent { get; set; default = false; }
+  public bool ns_top { get; set; default = false; }
+  public bool prefix_default_ns { get; set; default = false; }
+  public bool backup { get; set; default = true; }
+  public GLib.File file { get; set; }
+  public GXml.Node root {
+    owned get {
+      var r = doc->get_root_element ();
+      if (r == null) {
+        int found = 0;
+        for (int i = 0; i < childs.size; i++) {
+          GXml.Node n = childs.get (i);
+          if (n is GXml.Element) {
+            found++;
+            if (found == 1)
+              return n;
+          }
+        }
+        if (found > 1) {
+          GLib.warning ("Document have more than one root GXmlElement. Using first found");
+        }
+      } 
+      return new GElement (r);
+    }
+  }
+  public GXml.Node create_comment (string text)
+  {
+    var c = doc->new_comment (text);
+    return new GComment (c);
+  }
+  public GXml.Node create_pi (string target, string data)
+  {
+    var pi = doc->new_pi (target, data);
+    return new GProcessingInstruction (pi);
+  }
+  public GXml.Node create_element (string name)
+  {
+    var e = doc->new_raw_node (null, name, null);
+    return new GElement (e);
+  }
+  public GXml.Node create_text (string text)
+  {
+    var t = doc->new_text (text);
+    return new GText (t);
+  }
+  public GXml.Node create_cdata (string text)
+  {
+    var cd = doc->new_cdata_block (text, text.length);
+    return new GCDATA (cd);
+  }
+  public bool save (GLib.Cancellable? cancellable = null)
+    throws GLib.Error
+    requires (file != null)
+  {
+    return save_as (file, cancellable);
+  }
+  public bool save_as (GLib.File f, GLib.Cancellable? cancellable = null)
+  {
+    var buf = new Xml.Buffer ();
+    var tw = Xmlx.new_text_writer_memory (buf, 0);
+    GLib.Test.message ("Writing down to buffer");
+    write_document (tw);
+    GLib.Test.message ("Writing down to file");
+    GLib.Test.message ("TextWriter buffer:\n"+buf.content ());
+    var s = new GLib.StringBuilder ();
+    s.append (buf.content ());
+    try {
+      GLib.Test.message ("Writing down to file: Creating input stream");
+      var b = new GLib.MemoryInputStream.from_data (s.data, null);
+      GLib.Test.message ("Writing down to file: Replacing with backup");
+      var ostream = f.replace (null, backup, GLib.FileCreateFlags.NONE, cancellable);
+      ostream.splice (b, GLib.OutputStreamSpliceFlags.NONE);
+      ostream.close ();
+    } catch (GLib.Error e) {
+      GLib.warning ("Error on Save to file: "+e.message);
+      return false;
+    }
+    return true;
+  }
+  public virtual void write_document (Xml.TextWriter tw)
+  {
+    tw.start_document ();
+    tw.set_indent (indent);
+    // Root
+    if (root == null) {
+      tw.end_document ();
+    }
+    var dns = new ArrayList<string> ();
+#if DEBUG
+    GLib.message ("Starting writting Document Root node");
+#endif
+    start_node (tw, root, true, ref dns);
+#if DEBUG
+    GLib.message ("Ending writting Document Root node");
+#endif
+    tw.end_element ();
+#if DEBUG
+    GLib.message ("Ending Document");
+#endif
+    tw.end_document ();
+    tw.flush ();
+  }
+  public virtual void start_node (Xml.TextWriter tw, GXml.Node node, bool root, ref Gee.ArrayList<string> 
declared_ns)
+  {
+    int size = 0;
+#if DEBUG
+    GLib.message (@"Starting Node: start Node: '$(node.name)'");
+#endif
+    if (node is GXml.Element) {
+#if DEBUG
+    GLib.message (@"Starting Element... '$(node.name)'");
+    GLib.message (@"Element Document is Null... '$((node.document == null).to_string ())'");
+    GLib.message (@"Namespaces in Element... '$(node.namespaces.size)'");
+#endif
+      if (root) {
+        if (node.document.namespaces.size > 0) {
+          var dns = node.document.namespaces.get (0);
+          assert (dns != null);
+          if (prefix_default_ns) {
+            tw.start_element_ns (dns.prefix, node.name, dns.uri);
+            declared_ns.add (dns.uri);
+#if DEBUG
+              GLib.message (@"Declared NS: '$(dns.uri)' Total declared = $(declared_ns.size.to_string ())");
+#endif
+          }
+          else {
+            tw.start_element (node.name);
+            if (dns.prefix == null)
+              tw.write_attribute ("xmlns",dns.uri);// Write default namespace no prefix
+            else
+              tw.write_attribute ("xmlns:"+dns.prefix,dns.uri);
+            // Add to declared namespaces
+            declared_ns.add (dns.uri);
+#if DEBUG
+              GLib.message (@"Declared NS: $(dns.uri) Total declared = $(declared_ns.size.to_string ())");
+#endif
+          }
+          if (node.document.namespaces.size > 1 && node.document.ns_top) {
+            for (int i = 1; i < node.document.namespaces.size; i++) {
+              GXml.Namespace ns = node.document.namespaces.get (i);
+              if (ns.prefix == null) continue;
+              tw.write_attribute ("xmlns:"+ns.prefix, ns.uri);
+              declared_ns.add (ns.uri);
+#if DEBUG
+              GLib.message (@"Declared NS: '$(ns.uri)' Total declared = $(declared_ns.size.to_string ())");
+#endif
+            }
+          }
+        }
+        else
+          tw.start_element (node.name);
+      }
+      else {
+        if (node.namespaces.size > 0) {
+#if DEBUG
+      GLib.message (@"Starting Element: '$(node.name)' start with NS");
+#endif
+          if (node.document.ns_uri () == node.ns_uri ()) {
+#if DEBUG
+      GLib.message (@"Node '$(node.name)' Have Default NS");
+#endif
+            if (node.document.prefix_default_ns)  // Default NS at root element
+              tw.start_element_ns (node.ns_prefix (), node.name, null);
+            else // Don't prefix. Using default namespace and prefix_default_ns = false
+              tw.start_element (node.name);
+          }
+          else {
+#if DEBUG
+      GLib.message (@"No default NS in use for Node '$(node.name)'. Ns = '$(node.ns_uri ())'");
+#endif
+            if (node.ns_prefix () == null && !declared_ns.contains (node.ns_uri ())) {// Its a default ns 
for children
+              tw.start_element_ns (node.ns_prefix (), node.name, node.ns_uri ());
+              declared_ns.add (node.ns_uri ());
+#if DEBUG
+              GLib.message (@"Declared NS: '$(node.ns_uri ())' Total declared = $(declared_ns.size.to_string 
())");
+#endif
+            }
+            else {
+              if (node.document.ns_top || declared_ns.contains (node.ns_uri ()))
+                tw.start_element_ns (node.ns_prefix (), node.name, null);
+              else {
+                tw.start_element_ns (node.ns_prefix (), node.name, node.ns_uri ());
+                declared_ns.add (node.ns_uri ());
+#if DEBUG
+              GLib.message (@"Declared NS: $(node.ns_uri ()) Total declared = $(declared_ns.size.to_string 
())");
+#endif
+              }
+            }
+          }
+        } else {
+#if DEBUG
+      GLib.message (@"Starting Element: '$(node.name)' : start no NS: Check for default prefix_default_ns 
enabled");
+#endif
+          if (node.document.prefix_default_ns)
+            tw.start_element_ns (node.document.ns_prefix (), node.name, null);
+          else
+            tw.start_element (node.name);
+        }
+      }
+#if DEBUG
+    GLib.message (@"Starting Element '$(node.name)': writting attributes");
+#endif
+      foreach (GXml.Node attr in node.attrs.values) {
+        if (attr.namespaces.size > 0) {
+#if DEBUG
+    GLib.message (@"Starting Element '$(node.name)': write attribute '$(attr.name)' with NS");
+#endif
+          if (!declared_ns.contains (attr.ns_uri ())) {
+            size += tw.write_attribute_ns (attr.ns_prefix (), attr.name, attr.ns_uri (), attr.value);
+            declared_ns.add (attr.ns_uri ());
+#if DEBUG
+              GLib.message (@"Declared NS: $(attr.ns_uri ()) Total declared = $(declared_ns.size.to_string 
())");
+#endif
+          }
+          else
+            size += tw.write_attribute_ns (attr.ns_prefix (), attr.name, null, attr.value);
+        }
+        else {
+#if DEBUG
+    GLib.message (@"Starting Element '$(node.name)': write attribute '$(attr.name)' no NS");
+#endif
+          size += tw.write_attribute (attr.name, attr.value);
+        }
+        if (size > 1500)
+          tw.flush ();
+      }
+#if DEBUG
+    GLib.message (@"Starting Element: writting Node '$(node.name)' childs");
+#endif
+      foreach (GXml.Node n in node.childs) {
+#if DEBUG
+    GLib.message (@"Child Node is: $(n.get_type ().name ())");
+#endif
+        if (n is GXml.Element) {
+#if DEBUG
+    GLib.message (@"Starting Child Element: writting Node '$(n.name)'");
+#endif
+          if (node.namespaces.size > 0) {
+            if (node.document.namespaces.size > 0)
+              if (node.ns_uri () != node.document.ns_uri ())
+                if (n.namespaces.size == 0 && node.ns_prefix == null) // Apply parent ns
+                  n.set_namespace (node.ns_uri (), node.ns_prefix ());
+          }
+          start_node (tw, n, false, ref declared_ns);
+          size += tw.end_element ();
+          if (size > 1500)
+            tw.flush ();
+        }
+        if (n is GXml.Text) {
+          //GLib.message ("Writting Element's contents");
+          size += tw.write_string (node.value);
+          if (size > 1500)
+            tw.flush ();
+        }
+        if (n is GXml.Comment) {
+#if DEBUG
+    GLib.message (@"Starting Child Element: writting Comment '$(n.value)'");
+#endif
+          size += tw.write_comment (n.value);
+          if (size > 1500)
+            tw.flush ();
+        }
+        if (n is GXml.CDATA) {
+#if DEBUG
+    GLib.message (@"Starting Child Element: writting CDATA '$(n.value)'");
+#endif
+          size += Xmlx.text_writer_write_cdata (tw, n.value);
+          if (size > 1500)
+            tw.flush ();
+        }
+        if (n is GXml.ProcessingInstruction) {
+#if DEBUG
+    GLib.message (@"Starting Child Element: writting ProcessingInstruction '$(n.value)'");
+#endif
+          size += Xmlx.text_writer_write_pi (tw, ((ProcessingInstruction) n).target, 
((ProcessingInstruction) n).data);
+          if (size > 1500)
+            tw.flush ();
+        }
+      }
+    }
+  }
+  public override string to_string ()
+  {
+#if DEBUG
+    GLib.message ("TwDocument: to_string ()");
+#endif
+    Xml.Doc doc = new Xml.Doc ();
+    Xml.TextWriter tw = Xmlx.new_text_writer_doc (ref doc);
+    write_document (tw);
+    string str;
+    int size;
+    doc.dump_memory (out str, out size);
+    return str;
+  }
+  // HTML methods
+               public static int default_options {
+                       get {
+                               return Html.ParserOption.NONET | Html.ParserOption.NOWARNING | 
Html.ParserOption.NOERROR | Html.ParserOption.NOBLANKS;
+                       }
+               }
+               /**
+                * Search all { link GXml.Element} with a property called "class" and with a
+                * value as a class apply to a node.
+                */
+               public Gee.List<GXml.Node> get_elements_by_class_name (string klass) {
+                       var rl = new Gee.ArrayList<GXml.Node> ();
+                       var l = root.get_elements_by_property_value ("class", klass);
+                       foreach (GXml.Node n in l) {
+                               var p = n.attrs.get ("class");
+                               if (p == null) continue;
+                               if (" " in p.value) {
+                                       foreach (string ks in p.value.split (" ")) {
+                                               if (ks == klass)
+                                                       rl.add (n);
+                                       }
+                               } else if (klass == p.value) {
+                                       rl.add (n);
+                               }
+                       }
+                       return rl;
+               }
+               /**
+                * Get first node where 'id' attribute has given value.
+                */
+               public GXml.Node? get_element_by_id (string id) {
+                       var l = root.get_elements_by_property_value ("id", id);
+                       foreach (GXml.Node n in l) {
+                               var p = n.attrs.get ("id");
+                               if (p == null) continue;
+                               if (p.value == id) return n;
+                       }
+                       return null;
+               }
+}
diff --git a/gxml/GXmlElement.vala b/gxml/GXmlElement.vala
new file mode 100644
index 0000000..7c3d2e6
--- /dev/null
+++ b/gxml/GXmlElement.vala
@@ -0,0 +1,57 @@
+/* GElement.vala
+ *
+ * Copyright (C) 2016  Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *      Daniel Espinosa <esodan gmail com>
+ */
+
+using Gee;
+
+/**
+ * Class implemeting { link GXml.Element} interface, not tied to libxml-2.0 library.
+ */
+public class GXml.GElement : GXml.GNode, GXml.Element
+{
+  public GElement (Xml.Node *node) { _node = node; }
+  // GXml.Node
+  public override string value
+  {
+    owned get {
+      return content;
+    }
+    set { content = value; }
+  }
+  // GXml.Element
+  public void set_attr (string name, string value)
+  {
+    _node->new_prop (name, value);
+  }
+  public GXml.Node get_attr (string name)
+  {
+    return new GAttribute (_node->get_prop (name));
+  }
+  public void normalize () {}
+  public string content {
+    owned get {
+      return _node->get_content ().dup ();
+    }
+    set {
+      _node->set_content (value);
+    }
+  }
+  public string tag_name { owned get { return _node->name.dup (); } }
+}
diff --git a/gxml/GXmlHashMapAttr.vala b/gxml/GXmlHashMapAttr.vala
new file mode 100644
index 0000000..13db1ce
--- /dev/null
+++ b/gxml/GXmlHashMapAttr.vala
@@ -0,0 +1,175 @@
+/* -*- Mode: vala; indent-tabs-mode: nil; c-basic-offset: 0; tab-width: 2 -*- */
+/* GXmlHashMapAttr.vala
+ *
+ * Copyright (C) 2015  Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *      Daniel Espinosa <esodan gmail com>
+ */
+
+using Gee;
+
+public class GXml.GHashMapAttr : Gee.AbstractMap<string,GXml.Node>
+{
+  private Xml.Node *_node;
+  public GHashMapAttr (Xml.Node *node) {
+    _node = node;
+  }
+  
+  public class Entry : Gee.Map.Entry<string,GXml.Node> {
+    private Xml.Attr *_attr;
+    private GAttribute oattr;
+    public Entry (Xml.Attr *attr) {
+      _attr = attr;
+      oattr = new GAttribute (_attr);
+    }
+    public override string key { get { return _attr->name; } }
+    public override bool read_only { get { return true; } }
+    public override GXml.Node value {
+      get { return oattr; }
+      set {}
+    }
+  }
+  public override void clear () {
+    if (_node == null) return;
+    var p = _node->properties;
+    while (p != null) {
+      var pn = p;
+      p = p->next;
+      pn->remove ();
+    }
+  }
+  public override GXml.Node @get (string key) {
+    if (_node == null) return null;
+    var p = _node->get_prop (key);
+    return new GAttribute (p);
+  }
+  public override bool has (string key, GXml.Node value) { return has_key (key); }
+  public override bool has_key (string key) {
+    if (_node == null) return false;
+    var p = _node->properties;
+    while (p != null) {
+      if (p->name == key) return true;
+    }
+    return false;
+  }
+  public override Gee.MapIterator<string,GXml.Node> map_iterator () { return new Iterator (_node); }
+  public override void @set (string key, GXml.Node value) {
+    if (_node == null) return;
+    _node->new_prop (key, value  value);
+  }
+  public override bool unset (string key, out GXml.Node value = null) {
+    if (_node == null) return false;
+    value = null;
+    return (_node->set_prop (key, null)) != null;
+  }
+  public override Gee.Set<Gee.Map.Entry<string,GXml.Node>> entries {
+    owned get {
+      var l = new Gee.HashSet<Entry> ();
+      if (_node == null) return l;
+      var p = _node->properties;
+      while (p != null) {
+        var e = new Entry (p);
+        l.add (e);
+        p = p->next;
+      }
+      return l;
+    }
+  }
+  public override Gee.Set<string> keys {
+    owned get {
+      var l = new Gee.HashSet<string> ();
+      if (_node == null) return l;
+      var p = _node->properties;
+      while (p != null) {
+        l.add (p->name.dup ());
+      }
+      return l;
+    }
+  }
+  public override bool read_only { get { return false; } }
+  public override int size {
+    get {
+      var p = _node->properties;
+      int i = 0;
+      while (p != null) {
+        p = p->next;
+        i++;
+      }
+      return i;
+    }
+  }
+  public override Gee.Collection<GXml.Node> values {
+    owned get {
+      var l = new ArrayList<GXml.Node> ();
+      var p = _node->properties;
+      while (p != null) {
+        l.add (new GAttribute (p));
+        p = p->next;
+      }
+      return l;
+    }
+  }
+  public class Iterator : Object, MapIterator<string,GXml.Node> {
+    private Xml.Node *_node;
+    private Xml.Attr *_current;
+
+    public Iterator (Xml.Node *node) {
+      _node = node;
+      _current = null;
+    }
+
+    public string get_key () {
+      if (_current != null) _current->name.dup ();
+      return null;
+    }
+    public GXml.Node get_value () {
+      return new GAttribute (_current);
+    }
+    public bool has_next () {
+      if (_node->properties == null) return false;
+      if (_current != null)
+        if (_current->next == null) return false;
+      return true;
+    }
+    public bool next () {
+      if (_node->properties == null) return false;
+      if (_current == null)
+        _current = _node->properties;
+      if (_current->next == null) return false;
+      _current = _current->next;
+      return true;
+    }
+    public void set_value (GXml.Node value) {
+      if (_current == null) return;
+      if (_current->name == value.name) {
+        var p = _node->properties;
+        while (p != null) {
+          if (p->name == value.name) {
+            _node->set_prop (value.name, @value.value);
+          }
+        }
+      }
+    }
+    public void unset () {
+      if (_current == null) return;
+      _node->set_prop (_current->name, null);
+    }
+    public bool mutable { get { return false; } }
+    public bool read_only { get { return false; } }
+    public bool valid { get { return _current != null; } }
+  }
+}
diff --git a/gxml/GXmlListChildren.vala b/gxml/GXmlListChildren.vala
new file mode 100644
index 0000000..c10460f
--- /dev/null
+++ b/gxml/GXmlListChildren.vala
@@ -0,0 +1,237 @@
+/* -*- Mode: vala; indent-tabs-mode: nil; c-basic-offset: 0; tab-width: 2 -*- */
+/* GXmlListChildren.vala
+ *
+ * Copyright (C) 2015  Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *      Daniel Espinosa <esodan gmail com>
+ */
+
+using Gee;
+
+public class GXml.GListChildren : AbstractBidirList<GXml.Node>
+{
+  private Xml.Node *_node;
+  private bool _read_only = false;
+  public GListChildren (Xml.Node* node) {
+    _node = node;
+  }
+  public new override Gee.BidirListIterator<GXml.Node> bidir_list_iterator () {
+    return new Iterator (_node);
+  }
+  // List
+  public override GXml.Node @get (int index) {
+    if (_node == null) return null;
+    var n = _node->children;
+    int i = 0;
+    while (n != null) {
+      var t = (GXml.NodeType) n->type;
+      if (i == index) {
+        return GNode.to_gnode (n);
+      }
+      i++;
+      n = n->next;
+    }
+    return null;
+  }
+  public override int index_of (GXml.Node item) {
+    if (_node == null) return -1;
+    if (!(item is GNode)) return -1;
+    var n = _node->children;
+    int i = 0;
+    while (n != null) {
+      if (n == ((GNode) item).get_internal_node ()) return i;
+      n = n->next;
+      i++;
+    }
+    return -1;
+  }
+  /**
+   * This method is ignored by default.
+   */
+  public override void insert (int index, GXml.Node item) {}
+  public override  Gee.ListIterator<GXml.Node> list_iterator () { return new Iterator (_node); }
+  /**
+   * This method is ignored by default.
+   */
+  public override GXml.Node remove_at (int index) { return null; }
+  /**
+   * This method is ignored by default.
+   */
+  public override void @set (int index, GXml.Node item) {}
+  public override Gee.List<GXml.Node>? slice (int start, int stop) {
+    var l = new ArrayList<GXml.Node> ();
+    if (_node == null) return l;
+    var n = _node->children;
+    int i = 0;
+    while (n != null) {
+      if (i >= start && i <= stop) {
+        l.add (GNode.to_gnode (n));
+      }
+      n = n->next;
+      i++;
+    }
+    return l;
+  }
+  public override bool add (GXml.Node item) {
+    if (_node == null) return false;
+    if (!(item is GNamespace))
+      return (_node->add_child (((GNode) item).get_internal_node ())) != null;
+    else {
+      var ns = (GXml.Namespace) item;
+      return (_node->new_ns (ns.uri, ns.prefix)) != null;
+    }
+    return false;
+  }
+  public override void clear () {
+    if (_node == null) return;
+    _node->children->free_list ();
+  }
+  public override bool contains (GXml.Node item) {
+    if (_node == null) return false;
+    if (!(item is GXml.GNode)) return false;
+    var n = _node->children;
+    while (n != null) {
+      if (n == ((GXml.GNode) item).get_internal_node ()) return true;
+      n = n->next;
+    }
+    return false;
+  }
+  public override Gee.Iterator<GXml.Node> iterator () { return new Iterator (_node); }
+  public override bool remove (GXml.Node item) {
+    if (_node == null) return false;
+    if (!(item is GXml.GNode)) return false;
+    var n = _node->children;
+    while (n != null) {
+      if (n == ((GXml.GNode) item).get_internal_node ()) {
+        n->unlink ();
+        delete n;
+        return true;
+      }
+      n = n->next;
+    }
+    return false;
+  }
+  public override int size {
+    get {
+      if (_node == null) return -1;
+      int i = 0;
+      var n = _node->children;
+      while (n != null) {
+        i++;
+        n = n->next;
+      }
+      return i;
+    }
+  }
+  public override bool read_only { get { return false; } }
+  // Iterator
+  public class Iterator : Object, Traversable<GXml.Node>,
+                          Gee.Iterator<GXml.Node>,
+                          Gee.BidirIterator<GXml.Node>,
+                          Gee.ListIterator<GXml.Node>,
+                          BidirListIterator<GXml.Node> {
+    private Xml.Node *_node;
+    private Xml.Node *_current;
+    private int i = 0;
+    public Iterator (Xml.Node *node) {
+      _node = node;
+      _current = _node->children;
+    }
+    /**
+     * This method is ignored by default.
+     */
+    public void insert (GXml.Node item) {}
+    // ListIterator
+    /**
+     * This method is ignored by default.
+     */
+    public void add (GXml.Node item) {}
+    public int index () { return i; }
+    /**
+     * This method is ignored by default.
+     */
+    public new void @set (GXml.Node item) {}
+    // Iterator
+    public new GXml.Node @get () { return GNode.to_gnode (_node); }
+    public bool has_next () {
+      if (_node == null) return false;
+      if (_node->children == null) return false;
+      if (_current != null)
+        if (_current->next != null) return true;
+      return (_node->children->next != null);
+    }
+    public bool next () {
+      if (!has_next ()) return false;
+      if (_node->children == null) return false;
+      if (_current == null)
+        _current = _node->children;
+      if (_current->next == null) return false;
+      _current = _current->next;
+      return true;
+    }
+    public void remove () {
+      if (_current == null) return;
+      var n = _current;
+      _current = _current->prev;
+      n->unlink ();
+      delete n;
+    }
+    public bool read_only { get { return false; } }
+    public bool valid { get { return (_current != null); } }
+    public new bool @foreach (Gee.ForallFunc<GXml.Node> f) {
+      while (has_next ()) {
+        next ();
+        if (!f(@get())) return false;
+      }
+      return true;
+    }
+    public bool first () {
+      if (_node == null) return false;
+      if (_node->children == null) return false;
+      return (_current = _node->children) != null;
+    }
+    public bool has_previous () {
+      if (_node == null) return false;
+      if (_node->children == null) return false;
+      if (_current == null) return false;
+      if (_current->prev == null) return false;
+      return true;
+    }
+    public bool last () {
+      if (_node == null) return false;
+      if (_node->children == null) return false;
+      _current = _node->children;
+      while (_current->next != null) {
+        _current = _current->next;
+      }
+      return true;
+    }
+    public bool previous () {
+      if (_node == null) return false;
+      if (_node->children == null) return false;
+      if (_current == null) {
+        _current = _node->children;
+        return true;
+      }
+      while (_current->prev != null) {
+        _current = _current->prev;
+      }
+      return true;
+    }
+  }
+}
+
diff --git a/gxml/GXmlListNamespaces.vala b/gxml/GXmlListNamespaces.vala
new file mode 100644
index 0000000..43f8c5e
--- /dev/null
+++ b/gxml/GXmlListNamespaces.vala
@@ -0,0 +1,150 @@
+/* -*- Mode: vala; indent-tabs-mode: nil; c-basic-offset: 0; tab-width: 2 -*- */
+/* GXmlListNamespaces.vala
+ *
+ * Copyright (C) 2015  Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *      Daniel Espinosa <esodan gmail com>
+ */
+
+using Gee;
+
+public class GXml.GListNamespaces : Gee.AbstractList<GXml.Node>
+{
+  private Xml.Node *_node;
+  private bool _read_only = false;
+  public GListNamespaces (Xml.Node *node) {
+    _node = node;
+  }
+  // List
+  public override new GXml.Node @get (int index) {
+    if (_node == null) return null;
+    var ns = _node->ns_def;
+    int i = 0;
+    while (ns != null) {
+      if (i == index) {
+        return new GNamespace (ns);
+      }
+    }
+    return null;
+  }
+  public override int index_of (GXml.Node item) {
+    if (_node == null) return -1;
+    if (!(item is GNamespace)) return -1;
+    var ns = _node->ns_def;
+    int i = 0;
+    while (ns != null) {
+      if (((GNamespace) item).get_internal_ns () == ns) return i;
+      ns = ns->next;
+      i++;
+    }
+    return -1;
+  }
+  public override void insert (int index, GXml.Node item) {}
+  public override Gee.ListIterator<GXml.Node> list_iterator () { return new Iterator (_node); }
+  public override GXml.Node remove_at (int index) { return null; }
+  public override new void @set (int index, GXml.Node item) {}
+  public override Gee.List<GXml.Node>? slice (int start, int stop) {
+    var l = new ArrayList<GXml.Node> ();
+    if (_node == null) return l;
+    var ns = _node->ns_def;
+    int i = 0;
+    while (ns != null) {
+      if (i >= start && i <= stop) {
+        l.add (new GNamespace (ns));
+      }
+      ns = ns->next;
+      i++;
+    }
+    return l;
+  }
+  // Collection
+  public override bool add (GXml.Node item) {
+    if (!(item is Namespace)) return false;
+    if (_node == null) return false;
+    return (_node->new_ns (((Namespace) item).uri, ((Namespace) item).prefix)) != null;
+  }
+  public override void clear () {}
+  public override bool contains (GXml.Node item) {
+    if (!(item is GNamespace)) return false;
+    if (_node == null) return false;
+    var ns = _node->ns_def;
+    while (ns != null) {
+      if (ns == ((GNamespace) item).get_internal_ns ()) return true;
+    }
+    return false;
+  }
+  public override Gee.Iterator<GXml.Node> iterator () { return new Iterator (_node); }
+  public override bool remove (GXml.Node item) { return false; }
+  public override bool read_only { get { return false; } }
+  public override int size {
+    get {
+      if (_node == null) return -1;
+      var ns = _node->ns_def;
+      int i = 0;
+      while (ns != null) {
+        i++;
+        ns = ns->next;
+      }
+      return i;
+    }
+  }
+  public class Iterator : Object, Gee.Traversable<GXml.Node>, Gee.Iterator<GXml.Node>,
+                          Gee.ListIterator<GXml.Node> {
+    private Xml.Node *_node;
+    private Xml.Ns *_current;
+    private int i = -1;
+    public Iterator (Xml.Node *node) {
+      _node = node;
+    }
+    // ListIterator
+    public void add (GXml.Node item) {
+      if (_node == null) return;
+      if (!(item is GXml.Namespace)) return;
+      var ns = (GXml.Namespace) item;
+      _node->new_ns (ns.uri, ns.prefix);
+    }
+    public int index () { return i; }
+    public new void @set (GXml.Node item) {}
+    // Iterator
+    public new GXml.Node @get () { return new GNamespace (_current); }
+    public bool has_next ()  {
+      if (_node->ns_def == null) return false;
+      if (_current != null)
+        if (_current->next == null) return false;
+      return true;
+    }
+               public bool next () {
+      if (_node->ns_def == null) return false;
+      if (_current == null)
+        _current = _node->ns_def;
+      if (_current->next == null) return false;
+      _current = _current->next;
+      return true;
+    }
+    public void remove () {}
+    public bool read_only { get { return false; } }
+    public bool valid { get { return (_current != null); } }
+    // Traversable
+    public new bool @foreach (Gee.ForallFunc<GXml.Node> f) {
+      while (has_next ()) {
+        next ();
+        if (!f(@get())) return false;
+      }
+      return true;
+    }
+  }
+}
diff --git a/gxml/GXmlNamespace.vala b/gxml/GXmlNamespace.vala
new file mode 100644
index 0000000..8a884b3
--- /dev/null
+++ b/gxml/GXmlNamespace.vala
@@ -0,0 +1,45 @@
+/* GXmlNamespace.vala
+ *
+ * Copyright (C) 2016  Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *      Daniel Espinosa <esodan gmail com>
+ */
+
+using Gee;
+
+/**
+ * Class implemeting { link GXml.Namespace}
+ */
+public class GXml.GNamespace : GXml.GNode, GXml.Namespace
+{
+  private Xml.Ns *_ns;
+  public GNamespace (Xml.Ns* ns) { _ns = ns; }
+  public Xml.Ns* get_internal_ns () { return _ns; }
+  // GXml.Namespace
+  public string uri {
+    owned get {
+      if (_ns == null) return null;
+      return _ns->href.dup ();
+    }
+  }
+  public string @prefix {
+    owned get {
+      if (_ns == null) return null;
+      return _ns->prefix.dup ();
+    }
+  }
+}
diff --git a/gxml/GXmlNode.vala b/gxml/GXmlNode.vala
new file mode 100644
index 0000000..3b1eff3
--- /dev/null
+++ b/gxml/GXmlNode.vala
@@ -0,0 +1,115 @@
+/* -*- Mode: vala; indent-tabs-mode: nil; c-basic-offset: 0; tab-width: 2 -*- */
+/* ObjectModel.vala
+ *
+ * Copyright (C) 2015  Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *      Daniel Espinosa <esodan gmail com>
+ */
+
+using Gee;
+
+/**
+ * Base interface providing basic functionalities to all GXml interfaces.
+ */
+public abstract class GXml.GNode : Object, GXml.Node
+{
+  protected GXml.GDocument _doc;
+  protected Xml.Node *_node;
+  internal Xml.TextWriter *tw;
+
+       construct { Init.init (); }
+
+  // GXml.Node
+  public virtual bool set_namespace (string uri, string? prefix)
+  {
+    if (_node == null) return false;
+    return ((_node->new_ns (uri, prefix)) != null);
+  }
+  public virtual Gee.Map<string,GXml.Node> attrs { owned get { return new GHashMapAttr (_node); } }
+  public virtual Gee.BidirList<GXml.Node> children { owned get { return new GListChildren (_node); } }
+  public virtual Gee.List<GXml.Namespace> namespaces { owned get { return new GListNamespaces (_node); } }
+  public virtual GXml.Document document { get { return _doc; } }
+  public virtual GXml.NodeType type_node {
+    get {
+      if (_node == null) return GXml.NodeType.X_UNKNOWN;
+      return (GXml.NodeType) _node->type;
+    }
+  }
+  public virtual string name {
+    owned get {
+      if (_node == null) return "#noname";
+      return _node->name.dup ();
+    }
+  }
+
+  public virtual string @value {
+    owned get {
+      if (_node == null) return "";
+      return _node->get_content ();
+    }
+    set {
+      if (_node == null) return;
+      _node->set_content (value);
+    }
+  }
+  public virtual string to_string () { return get_type ().name (); }
+  public Xml.Node* get_internal_node () { return _node; }
+  // Static
+  public static GXml.Node to_gnode (Xml.Node *node) {
+    var t = (GXml.NodeType) node->type;
+    switch (t) {
+      case GXml.NodeType.ELEMENT:
+        return new GElement (node);
+        break;
+      case GXml.NodeType.ATTRIBUTE:
+        return new GAttribute ((Xml.Attr*) node);
+        break;
+      case GXml.NodeType.TEXT:
+        return new GText (node);
+        break;
+      case GXml.NodeType.CDATA_SECTION:
+        return new GCDATA (node);
+        break;
+      case GXml.NodeType.ENTITY_REFERENCE:
+        return null;
+        break;
+      case GXml.NodeType.ENTITY:
+        return null;
+        break;
+      case GXml.NodeType.PROCESSING_INSTRUCTION:
+        return new GProcessingInstruction (node);
+        break;
+      case GXml.NodeType.COMMENT:
+        return new GComment (node);
+        break;
+      case GXml.NodeType.DOCUMENT:
+        return new GDocument.from_doc (node->doc);
+        break;
+      case GXml.NodeType.DOCUMENT_TYPE:
+        return null;
+        break;
+      case GXml.NodeType.DOCUMENT_FRAGMENT:
+        return null;
+        break;
+      case GXml.NodeType.NOTATION:
+        return null;
+        break;
+    }
+    return null;
+  }
+}
+
diff --git a/gxml/GXmlProcessingInstruction.vala b/gxml/GXmlProcessingInstruction.vala
new file mode 100644
index 0000000..c7a8711
--- /dev/null
+++ b/gxml/GXmlProcessingInstruction.vala
@@ -0,0 +1,36 @@
+/* GXmlProcessingInstruction.vala
+ *
+ * Copyright (C) 2016  Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *      Daniel Espinosa <esodan gmail com>
+ */
+
+using Gee;
+
+/**
+ * Class implemeting { link GXml.ProcessingInstruction} interface, not tied to libxml-2.0 library.
+ */
+public class GXml.GProcessingInstruction : GXml.GNode, GXml.ProcessingInstruction
+{
+  public GProcessingInstruction (Xml.Node *node)
+  {
+    _node = node;
+  }
+  // GXml.ProcessingInstruction
+  public string target { owned get { return name; } }
+  public string data { owned get { return base.value; } }
+}
diff --git a/gxml/GXmlText.vala b/gxml/GXmlText.vala
new file mode 100644
index 0000000..4c02115
--- /dev/null
+++ b/gxml/GXmlText.vala
@@ -0,0 +1,35 @@
+/* GXmlText.vala
+ *
+ * Copyright (C) 2016  Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *      Daniel Espinosa <esodan gmail com>
+ */
+
+using Gee;
+
+/**
+ * Class implemeting { link GXml.Text} interface, not tied to libxml-2.0 library.
+ */
+public class GXml.GText : GXml.GNode, GXml.Text
+{
+  public GText (Xml.Node *node)
+  {
+    _node = node;
+  }
+  // GXml.Text
+  public string str { owned get { return base.value; } }
+}
diff --git a/gxml/Makefile.am b/gxml/Makefile.am
index 3d8e619..fab1881 100644
--- a/gxml/Makefile.am
+++ b/gxml/Makefile.am
@@ -83,7 +83,19 @@ sources = \
        TwNode.vala \
        TwProcessingInstruction.vala \
        TwText.vala \
-       GHtml.vala
+       GHtml.vala \
+       GXmlAttribute.vala \
+       GXmlComment.vala \
+       GXmlCDATA.vala \
+       GXmlDocument.vala \
+       GXmlElement.vala \
+       GXmlNamespace.vala \
+       GXmlNode.vala \
+       GXmlProcessingInstruction.vala \
+       GXmlText.vala \
+       GXmlHashMapAttr.vala \
+       GXmlListChildren.vala \
+       GXmlListNamespaces.vala
 
 
 ### General Compilation flags
diff --git a/gxml/Namespace.vala b/gxml/Namespace.vala
index 7725e0e..0a18191 100644
--- a/gxml/Namespace.vala
+++ b/gxml/Namespace.vala
@@ -36,13 +36,13 @@ public interface GXml.Namespace : Object
   /**
    * Read-only property to get namespace's URI.
    */
-  public abstract string uri { get; }
+  public abstract string uri { owned get; }
   /**
    * Read-only property to get namespace's prefix.
    *
    * Prefix should be added to { link GXml.Element} or { link GXml.Attribute}
    * name in order to apply a given namespace, unless it is the default.
    */
-  public abstract string prefix { get; }
+  public abstract string prefix { owned get; }
 }
 
diff --git a/gxml/Node.vala b/gxml/Node.vala
index 7c67e18..ca62760 100644
--- a/gxml/Node.vala
+++ b/gxml/Node.vala
@@ -30,26 +30,34 @@ public interface GXml.Node : Object
   /**
    * Collection of Namespaces applied to this { link GXml.Node}.
    */
-  public abstract Gee.List<GXml.Namespace> namespaces { get; }
+  public abstract Gee.List<GXml.Namespace> namespaces { owned get; }
   /**
    * Collection of { link GXml.Node} as childs.
    *
    * Depend on { link GXml.Node} type, this childs could of different, like,
    * elements, element's contents or properties.
    */
-  public abstract Gee.BidirList<GXml.Node> childs { get; }
+  [Deprecated (since="0.10.0", replace="children")]
+  public virtual Gee.BidirList<GXml.Node> childs { owned get { return children; } }
+  /**
+   * Collection of { link GXml.Node} as childs.
+   *
+   * Depend on { link GXml.Node} type, this childs could of different, like,
+   * elements, element's contents or properties.
+   */
+  public abstract Gee.BidirList<GXml.Node> children { owned get; }
   /**
    * Attributes in this { link GXml.Node}.
    */
-  public abstract Gee.Map<string,GXml.Node> attrs { get; }
+  public abstract Gee.Map<string,GXml.Node> attrs { owned get; }
   /**
    * Node's name. The meaning differs, depending on node's type.
    */
-  public abstract string name { get; }
+  public abstract string name { owned get; }
   /**
    * Node's value. The meaning differs, depending on node's type.
    */
-  public abstract string @value { get; set; }
+  public abstract string @value { owned get; set; }
   /**
    * Node's type as a enumeration.
    */
diff --git a/gxml/ProcessingInstruction.vala b/gxml/ProcessingInstruction.vala
index 477f45e..91c19b0 100644
--- a/gxml/ProcessingInstruction.vala
+++ b/gxml/ProcessingInstruction.vala
@@ -30,9 +30,9 @@ public interface GXml.ProcessingInstruction : Object, GXml.Node
   /**
    * The target for the processing instruction, like "xml-stylesheet".
    */
-  public abstract string target  { get; }
+  public abstract string target  { owned get; }
   /**
    * The data used by the target, like {{{href="style.xsl" type="text/xml"}}}
    */
-  public abstract string data { get; }
+  public abstract string data { owned get; }
 }
diff --git a/gxml/Serializable.vala b/gxml/Serializable.vala
index a133416..c174951 100644
--- a/gxml/Serializable.vala
+++ b/gxml/Serializable.vala
@@ -83,7 +83,7 @@ namespace GXml {
      *
      * This property is ignored on serialisation.
      */
-    public abstract Gee.Map<string,GXml.Attribute>    unknown_serializable_properties { get; }
+    public abstract Gee.Map<string,GXml.Attribute>    unknown_serializable_properties { owned get; }
 
     
     /**
@@ -105,7 +105,7 @@ namespace GXml {
      *
      * This property is ignored on serialisation.
      */
-    public abstract Gee.Collection<GXml.Node>    unknown_serializable_nodes { get; }
+    public abstract Gee.Collection<GXml.Node>    unknown_serializable_nodes { owned get; }
 
     /**
      * Used to add content in an { link GXml.Element}.
diff --git a/gxml/SerializableGeeArrayList.vala b/gxml/SerializableGeeArrayList.vala
index c152af3..bc1f300 100644
--- a/gxml/SerializableGeeArrayList.vala
+++ b/gxml/SerializableGeeArrayList.vala
@@ -37,14 +37,14 @@ public class GXml.SerializableArrayList<G> : Gee.ArrayList<G>, Serializable, Ser
 
   public Gee.Map<string,GXml.Attribute> unknown_serializable_properties
   {
-    get {
-      return _unknown_serializable_property;
+    owned get {
+      return (Gee.Map<string,GXml.Attribute>) _unknown_serializable_property.ref ();
     }
   }
   public Gee.Collection<GXml.Node> unknown_serializable_nodes
   {
-    get {
-      return _unknown_serializable_nodes;
+    owned get {
+      return (Gee.Collection<GXml.Node>) _unknown_serializable_nodes.ref ();
     }
   }
   protected ParamSpec[] properties { get; set; }
diff --git a/gxml/SerializableGeeDualKeyMap.vala b/gxml/SerializableGeeDualKeyMap.vala
index 06f6a48..50108db 100644
--- a/gxml/SerializableGeeDualKeyMap.vala
+++ b/gxml/SerializableGeeDualKeyMap.vala
@@ -119,14 +119,14 @@ public class GXml.SerializableDualKeyMap<P,S,V> : Object, Serializable, Serializ
   Gee.ArrayList<GXml.Node> _unknown_serializable_nodes = new Gee.ArrayList<GXml.Node> ();
   public Gee.Map<string,GXml.Attribute> unknown_serializable_properties
   {
-    get {
-      return _unknown_serializable_property;
+    owned get {
+      return (Gee.Map<string,GXml.Attribute>) _unknown_serializable_property.ref ();
     }
   }
   public Gee.Collection<GXml.Node> unknown_serializable_nodes
   {
-    get {
-      return _unknown_serializable_nodes;
+    owned get {
+      return (Gee.Collection<GXml.Node>) _unknown_serializable_nodes.ref ();
     }
   }
   protected ParamSpec[] properties { get; set; }
diff --git a/gxml/SerializableGeeHashMap.vala b/gxml/SerializableGeeHashMap.vala
index cc14f2e..952edaf 100644
--- a/gxml/SerializableGeeHashMap.vala
+++ b/gxml/SerializableGeeHashMap.vala
@@ -35,14 +35,14 @@ public class GXml.SerializableHashMap<K,V> : Gee.HashMap<K,V>, Serializable, Ser
 
   public Gee.Map<string,GXml.Attribute> unknown_serializable_properties
   {
-    get {
-      return _unknown_serializable_property;
+    owned get {
+      return (Gee.Map<string,GXml.Attribute>) _unknown_serializable_property.ref ();
     }
   }
   public Gee.Collection<GXml.Node> unknown_serializable_nodes
   {
-    get {
-      return _unknown_serializable_nodes;
+    owned get {
+      return (Gee.Collection<GXml.Node>) _unknown_serializable_nodes.ref ();
     }
   }
   protected ParamSpec[] properties { get; set; }
diff --git a/gxml/SerializableGeeTreeMap.vala b/gxml/SerializableGeeTreeMap.vala
index a83b5eb..b8c48c2 100644
--- a/gxml/SerializableGeeTreeMap.vala
+++ b/gxml/SerializableGeeTreeMap.vala
@@ -35,14 +35,14 @@ public class GXml.SerializableTreeMap<K,V> : Gee.TreeMap<K,V>, Serializable, Ser
 
   public Gee.Map<string,GXml.Attribute> unknown_serializable_properties
   {
-    get {
-      return _unknown_serializable_property;
+    owned get {
+      return (Gee.Map<string,GXml.Attribute>) _unknown_serializable_property.ref ();
     }
   }
   public Gee.Collection<GXml.Node> unknown_serializable_nodes
   {
-    get {
-      return _unknown_serializable_nodes;
+    owned get {
+      return (Gee.Collection<GXml.Node>) _unknown_serializable_nodes.ref ();
     }
   }
   protected ParamSpec[] properties { get; set; }
diff --git a/gxml/SerializableJson.vala b/gxml/SerializableJson.vala
index 012867d..1cf9b77 100644
--- a/gxml/SerializableJson.vala
+++ b/gxml/SerializableJson.vala
@@ -76,14 +76,14 @@ public class GXml.SerializableJson : GLib.Object, GXml.Serializable
 
   public Gee.Map<string,GXml.Attribute> unknown_serializable_properties
   {
-    get {
-      return _unknown_serializable_property;
+    owned get {
+      return (Gee.Map<string,GXml.Attribute>) _unknown_serializable_property.ref ();
     }
   }
   public Gee.Collection<GXml.Node> unknown_serializable_nodes
   {
-    get {
-      return _unknown_serializable_nodes;
+    owned get {
+      return (Gee.Collection<GXml.Node>) _unknown_serializable_nodes.ref ();
     }
   }
 
diff --git a/gxml/SerializableObjectModel.vala b/gxml/SerializableObjectModel.vala
index 24e3d56..1ed66cc 100644
--- a/gxml/SerializableObjectModel.vala
+++ b/gxml/SerializableObjectModel.vala
@@ -53,14 +53,14 @@ public abstract class GXml.SerializableObjectModel : Object, Serializable
    */
   public Gee.Map<string,GXml.Attribute> unknown_serializable_properties
   {
-    get {
+    owned get {
       if (_doc == null) init_unknown_doc ();
       return (Gee.Map<string,GXml.Attribute>) _doc.root.attrs;
     }
   }
   public Gee.Collection<GXml.Node> unknown_serializable_nodes
   {
-    get {
+    owned get {
       if (_doc == null) init_unknown_doc ();
       return _doc.root.childs;
     }
diff --git a/gxml/Text.vala b/gxml/Text.vala
index 385795e..3b43182 100644
--- a/gxml/Text.vala
+++ b/gxml/Text.vala
@@ -29,5 +29,5 @@ public interface GXml.Text : Object, GXml.Node
   /**
    * This should be implemented by returning { link GXml.Node.value}
    */
-  public abstract string str { get; }
+  public abstract string str { owned get; }
 }
diff --git a/gxml/TwAttribute.vala b/gxml/TwAttribute.vala
index b7fd661..c00e062 100644
--- a/gxml/TwAttribute.vala
+++ b/gxml/TwAttribute.vala
@@ -1,6 +1,6 @@
 /* TwAttribute.vala
  *
- * Copyright (C) 2015  Daniel Espinosa <esodan gmail com>
+ * Copyright (C) 2015-2016  Daniel Espinosa <esodan gmail com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -33,4 +33,17 @@ public class GXml.TwAttribute : GXml.TwNode, GXml.Attribute
     _name = name;
     _value = value;
   }
+  public Namespace @namespace {
+    owned get {
+      return (Namespace) namespaces.get (0).ref ();
+    }
+    set {
+      namespaces.add (value);
+    }
+  }
+  public string prefix {
+    owned get {
+      return @namespace.prefix;
+    }
+  }
 }
diff --git a/gxml/TwCDATA.vala b/gxml/TwCDATA.vala
index fcb5546..053e38e 100644
--- a/gxml/TwCDATA.vala
+++ b/gxml/TwCDATA.vala
@@ -38,9 +38,9 @@ public class GXml.TwCDATA : GXml.TwNode, GXml.CDATA
   }
   // GXml.Node
   public override string @value {
-    get { return _str; }
+    owned get { return _str.dup (); }
     set {}
   }
   // GXml.CDATA
-  public string str { get { return _str; } }
+  public string str { owned get { return _str.dup (); } }
 }
diff --git a/gxml/TwComment.vala b/gxml/TwComment.vala
index 3f97e64..c053e60 100644
--- a/gxml/TwComment.vala
+++ b/gxml/TwComment.vala
@@ -38,9 +38,9 @@ public class GXml.TwComment : GXml.TwNode, GXml.Comment
   }
   // GXml.Node
   public override string @value {
-    get { return _str; }
+    owned get { return _str.dup (); }
     set {  }
   }
   // GXml.Comment
-  public string str { get { return _str; } }
+  public string str { owned get { return _str.dup (); } }
 }
diff --git a/gxml/TwDocument.vala b/gxml/TwDocument.vala
index 2780beb..aca7887 100644
--- a/gxml/TwDocument.vala
+++ b/gxml/TwDocument.vala
@@ -69,7 +69,7 @@ public class GXml.TwDocument : GXml.TwNode, GXml.Document
   public bool backup { get; set; default = true; }
   public GLib.File file { get; set; }
   public GXml.Node root {
-    get {
+    owned get {
       if (_root == null) {
         int found = 0;
         for (int i = 0; i < childs.size; i++) {
diff --git a/gxml/TwElement.vala b/gxml/TwElement.vala
index b99e3bf..8077378 100644
--- a/gxml/TwElement.vala
+++ b/gxml/TwElement.vala
@@ -36,9 +36,9 @@ public class GXml.TwElement : GXml.TwNode, GXml.Element
   // GXml.Node
   public override string value
   {
-    get {
+    owned get {
       calculate_content ();
-      return _content;
+      return _content.dup ();
     }
     set { update_content (value); }
   }
@@ -53,13 +53,13 @@ public class GXml.TwElement : GXml.TwNode, GXml.Element
   public string content {
     owned get {
       calculate_content ();
-      return _content;
+      return _content.dup ();
     }
     set {
       update_content (value);
     }
   }
-  public string tag_name { get { return name; } }
+  public string tag_name { owned get { return name; } }
   private void calculate_content ()
   {
     _content = "";
diff --git a/gxml/TwNamespace.vala b/gxml/TwNamespace.vala
index 195c475..24948cb 100644
--- a/gxml/TwNamespace.vala
+++ b/gxml/TwNamespace.vala
@@ -37,6 +37,6 @@ public class GXml.TwNamespace : GXml.TwNode, GXml.Namespace
     _prefix = prefix;
   }
   // GXml.Namespace
-  public string uri { get { return _uri; } }
-  public string @prefix { get { return _prefix; } }
+  public string uri { owned get { return _uri.dup (); } }
+  public string @prefix { owned get { return _prefix.dup (); } }
 }
diff --git a/gxml/TwNode.vala b/gxml/TwNode.vala
index 0f34bfa..95f2762 100644
--- a/gxml/TwNode.vala
+++ b/gxml/TwNode.vala
@@ -27,7 +27,7 @@ using Gee;
 public abstract class GXml.TwNode : Object, GXml.Node
 {
   protected Gee.HashMap<string,GXml.Node> _attrs = new Gee.HashMap<string,GXml.Node> ();
-  protected Gee.ArrayList<GXml.Node> _childs = new Gee.ArrayList<GXml.Node> ();
+  protected Gee.ArrayList<GXml.Node> _children = new Gee.ArrayList<GXml.Node> ();
   protected Gee.ArrayList<GXml.Node> _namespaces = new Gee.ArrayList<GXml.Node> ();
   protected string _name = null;
   protected string _value = null;
@@ -54,11 +54,11 @@ public abstract class GXml.TwNode : Object, GXml.Node
     return true;
   }
   public virtual string to_string () { return get_type ().name (); }
-  public virtual Gee.Map<string,GXml.Node> attrs { get { return _attrs; } }
-  public virtual Gee.BidirList<GXml.Node> childs { get { return _childs; } }
+  public virtual Gee.Map<string,GXml.Node> attrs { owned get { return (Gee.Map<string,GXml.Node>) _attrs.ref 
(); } }
+  public virtual Gee.BidirList<GXml.Node> children { owned get { return (Gee.BidirList<GXml.Node>) 
_children.ref (); } }
   public virtual GXml.Document document { get { return _doc; } }
-  public virtual string name { get { return _name; } }
-  public virtual Gee.List<GXml.Namespace> namespaces { get { return _namespaces; } }
+  public virtual string name { owned get { return _name.dup (); } }
+  public virtual Gee.List<GXml.Namespace> namespaces { owned get { return (Gee.List<GXml.Namespace>) 
_namespaces.ref (); } }
   public virtual GXml.NodeType type_node { get { return GXml.NodeType.DOCUMENT; } }
-  public virtual string value { get { return _value; } set  { _value = value; } }
+  public virtual string value { owned get { return _value.dup (); } set  { _value = value; } }
 }
diff --git a/gxml/TwProcessingInstruction.vala b/gxml/TwProcessingInstruction.vala
index 1932d4c..f31c4b6 100644
--- a/gxml/TwProcessingInstruction.vala
+++ b/gxml/TwProcessingInstruction.vala
@@ -40,10 +40,10 @@ public class GXml.TwProcessingInstruction : GXml.TwNode, GXml.ProcessingInstruct
   }
   // GXml.Node
   public override string @value {
-    get { return _data; }
+    owned get { return _data.dup (); }
     set {}
   }
   // GXml.ProcessingInstruction
-  public string target { get { return _target; } }
-  public string data { get { return _data; } }
+  public string target { owned get { return _target.dup (); } }
+  public string data { owned get { return _data.dup (); } }
 }
diff --git a/gxml/TwText.vala b/gxml/TwText.vala
index 5b8d347..1844455 100644
--- a/gxml/TwText.vala
+++ b/gxml/TwText.vala
@@ -39,9 +39,9 @@ public class GXml.TwText : GXml.TwNode, GXml.Text
   }
   // GXml.Node
   public override string @value {
-    get { return _str; }
+    owned get { return _str.dup (); }
     set { _str = value; }
   }
   // GXml.Text
-  public string str { get { return _str; } }
+  public string str { owned get { return _str.dup (); } }
 }
diff --git a/gxml/libxml-Attr.vala b/gxml/libxml-Attr.vala
index bdb4b1b..def42bf 100644
--- a/gxml/libxml-Attr.vala
+++ b/gxml/libxml-Attr.vala
@@ -2,7 +2,7 @@
 /* Attr.vala
  *
  * Copyright (C) 2011-2013  Richard Schwarting <aquarichy gmail com>
- * Copyright (C) 2011,2015  Daniel Espinosa <esodan gmail com>
+ * Copyright (C) 2011,2015-2016  Daniel Espinosa <esodan gmail com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -181,9 +181,9 @@ namespace GXml {
                 * URL: [[http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-1112119403]]
                 */
                public override string name {
-                       get {
+                       owned get {
                                // TODO: make sure that this is the right name, and that ownership is correct
-                               return this.node_name;
+                               return this.node_name.dup ();
                        }
                }
 
@@ -214,8 +214,8 @@ namespace GXml {
                 * URL: [[http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-221662474]]
                 */
                public override string value {
-                       get {
-                               return this.node_value;
+                       owned get {
+                               return this.node_value.dup ();
                        }
                        set {
                                this.node_value = value;
@@ -236,6 +236,26 @@ namespace GXml {
                public override string stringify (bool format = false, int level = 0) {
                        return "Attr(%s=\"%s\")".printf (this.name, this.value);
                }
+               // GXml.Attribute
+               public string prefix {
+                       owned get {
+                               if (node == null) return "";
+                               if (node->ns == null) return "";
+                               return node->ns->prefix.dup ();
+                       }
+               }
+               public Namespace @namespace {
+                       owned get {
+                               return new NamespaceAttr (node->ns, this.owner_document);
+                       }
+                       set {
+                               if (node == null) return;
+                               if (node->doc == null) return;
+                               if (node->parent == null) return;
+                               var ns = node->parent->new_ns (value.uri, value.prefix);
+                               node->ns = ns;
+                       }
+               }
        }
 
 }
diff --git a/gxml/libxml-Comment.vala b/gxml/libxml-Comment.vala
index ae55a04..c9a0c32 100644
--- a/gxml/libxml-Comment.vala
+++ b/gxml/libxml-Comment.vala
@@ -45,6 +45,6 @@ public class GXml.xComment : GXml.xCharacterData, GXml.Comment {
                }
        }
        // GXml.Comment interface
-       public string str { get { return this.data; } }
+       public string str { owned get { return this.data; } }
 
 }
diff --git a/gxml/libxml-Document.vala b/gxml/libxml-Document.vala
index 831f899..2d21f8c 100644
--- a/gxml/libxml-Document.vala
+++ b/gxml/libxml-Document.vala
@@ -431,7 +431,7 @@ namespace GXml {
                 *
                 * @throws GXml.Error A { link GXml.Error} if an error occurs while reading the stream
                 */
-               public xDocument.from_stream (InputStream instream, Cancellable? can = null) throws 
GXml.Error {
+               public xDocument.from_stream (InputStream instream, Cancellable? can = null) throws 
GLib.Error {
                        Xml.Error* e = null;
                        string errmsg = null;
                        var ostream = new MemoryOutputStream.resizable ();
@@ -486,6 +486,7 @@ namespace GXml {
                public xDocument.from_string_with_options (string xml, string? url = null,
                                                          string? encoding = null,
                                                          int options = 0)
+                                                         throws GLib.Error
                {
                  Xml.Doc *doc;
                        Xmlx.reset_last_error ();
@@ -998,7 +999,7 @@ namespace GXml {
                public bool prefix_default_ns { get; set; default = false; }
                public bool backup { get; set; default = true; }
                public GLib.File file { get; set; }
-               public virtual GXml.Node root { get { return document_element; } }
+               public virtual GXml.Node root { owned get { return (GXml.Node) document_element.ref (); } }
                public GXml.Node create_text (string str) { return (GXml.Node) this.create_text_node (str); }
                public GXml.Node create_comment (string text) { return create_managed_comment (text); }
                public GXml.Node create_cdata (string text) { return create_cdata_section (text); }
diff --git a/gxml/libxml-DocumentType.vala b/gxml/libxml-DocumentType.vala
index 2cde22c..007441e 100644
--- a/gxml/libxml-DocumentType.vala
+++ b/gxml/libxml-DocumentType.vala
@@ -57,9 +57,9 @@ namespace GXml {
                 * {{{ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd";> }}}
                 */
                public override string name {
-                       get {
+                       owned get {
                                // TODO: is it possible for int_subset and ext_subset to have different names?
-                               return this.int_subset->name;
+                               return this.int_subset->name.dup ();
                        }
                }
 
diff --git a/gxml/libxml-Element.vala b/gxml/libxml-Element.vala
index d73f8ca..ed18fe4 100644
--- a/gxml/libxml-Element.vala
+++ b/gxml/libxml-Element.vala
@@ -55,11 +55,11 @@ namespace GXml {
                 * URL: [[http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-104682815]]
                 */
                public string tag_name {
-                       get {
+                       owned get {
                                // This is the same as node_name from Node:
                                // http://www.w3.org/TR/DOM-Level-1/level-one-core.html
                                // TODO: is this the same as tagname from xDocument's get_elem_by...?
-                               return base.node_name;
+                               return base.node_name.dup ();
                        }
                }
 
diff --git a/gxml/libxml-NamespaceAttr.vala b/gxml/libxml-NamespaceAttr.vala
index 3ec60fa..228ab0f 100644
--- a/gxml/libxml-NamespaceAttr.vala
+++ b/gxml/libxml-NamespaceAttr.vala
@@ -123,13 +123,13 @@ namespace GXml {
                }
                // GXml.Namespace interface implementations
                public string uri {
-                       get {
-                               return defined_namespace_uri;
+                       owned get {
+                               return defined_namespace_uri.dup ();
                        }
                }
                public string prefix {
-                       get {
-                               return defined_prefix;
+                       owned get {
+                               return defined_prefix.dup ();
                        }
                }
        }
diff --git a/gxml/libxml-Node.vala b/gxml/libxml-Node.vala
index c10ee02..7f3f647 100644
--- a/gxml/libxml-Node.vala
+++ b/gxml/libxml-Node.vala
@@ -501,11 +501,11 @@ namespace GXml {
                }
                
                // GXml.Node interface implementations
-               public virtual Gee.List<GXml.Namespace> namespaces { get { return namespace_definitions; } }
-               public virtual Gee.BidirList<GXml.Node> childs { get { return (BidirList<GXml.Node>) 
child_nodes; } }
-               public virtual Gee.Map<string,GXml.Node> attrs { get { return (Map<string,GXml.Node>) 
attributes; } }
-               public virtual string name { get { return node_name; } }
-               public virtual string @value { get { return node_value; } set { node_value = value; } }
+               public virtual Gee.List<GXml.Namespace> namespaces { owned get { return 
(Gee.List<GXml.Namespace>) namespace_definitions.ref (); } }
+               public virtual Gee.BidirList<GXml.Node> children { owned get { return (BidirList<GXml.Node>) 
child_nodes.ref (); } }
+               public virtual Gee.Map<string,GXml.Node> attrs { owned get { return (Map<string,GXml.Node>) 
attributes.ref (); } }
+               public virtual string name { owned get { return node_name.dup (); } }
+               public virtual string @value { owned get { return node_value.dup (); } set { node_value = 
value; } }
                public GXml.NodeType type_node { get { return node_type; } }
                public virtual string to_string () { return stringify (); }
                public GXml.Document document { get { return this.owner_document; } }
diff --git a/gxml/libxml-ProcessingInstruction.vala b/gxml/libxml-ProcessingInstruction.vala
index 543aa12..4a80ca6 100644
--- a/gxml/libxml-ProcessingInstruction.vala
+++ b/gxml/libxml-ProcessingInstruction.vala
@@ -53,15 +53,15 @@ namespace GXml {
                 * The target for the processing instruction, like "xml-stylesheet".
                 */
                public string target {
-                       get { return _target; }
+                       owned get { return _target.dup (); }
                }
 
                /**
                 * The data used by the target, like {{{href="style.xsl" type="text/xml"}}}
                 */
                public string data /* throws DomError (not supported yet) */ {
-                       get {
-                               return _data;
+                       owned get {
+                               return _data.dup ();
                        }
                }
                /**
@@ -69,7 +69,7 @@ namespace GXml {
                 */
                public override string node_name {
                        get {
-                               return this.target;
+                               return this._target;
                        }
                        private set {
                        }
@@ -79,7 +79,7 @@ namespace GXml {
                 */
                public override string? node_value {
                        get {
-                               return this.data;
+                               return this._data;
                        }
                        private set {
                        }
diff --git a/gxml/libxml-Text.vala b/gxml/libxml-Text.vala
index 80ca876..956a8fd 100644
--- a/gxml/libxml-Text.vala
+++ b/gxml/libxml-Text.vala
@@ -99,6 +99,6 @@ namespace GXml {
                        return other;
                }
                // Interface GXml.Text
-               public string str { get { return this.data; } }
+               public string str { owned get { return this.data; } }
        }
 }


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