[gxml] API change: most methods now returns owned values
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gxml] API change: most methods now returns owned values
- Date: Fri, 5 Feb 2016 15:35:02 +0000 (UTC)
commit b5f55ca777ee1cddfb68b99965653c7350af9b6c
Author: Daniel Espinosa <esodan gmail com>
Date: Thu Feb 4 18:27:01 2016 -0600
API change: most methods now returns owned values
* Change required for GNode series implementation, due to
use internal pointer managed by libmxl2, then objects
are created when needed no reference is kept
* All implementations ported to new API on GXml.Node*
* TwDocument.write_document now support any GXml.Document
* Added initial tests for HtmlDocument, actualy failing
on search elements with given "id"
gxml/Document.vala | 2 +-
gxml/GXmlAttribute.vala | 3 +-
gxml/GXmlCDATA.vala | 8 +-
gxml/GXmlComment.vala | 8 +-
gxml/GXmlDocument.vala | 325 +++++------------------------------
gxml/GXmlElement.vala | 7 +-
gxml/GXmlHashMapAttr.vala | 24 ++-
gxml/GXmlListChildren.vala | 20 ++-
gxml/GXmlListNamespaces.vala | 4 +-
gxml/GXmlNode.vala | 22 ++--
gxml/GXmlProcessingInstruction.vala | 3 +-
gxml/GXmlText.vala | 8 +-
gxml/Node.vala | 16 ++-
gxml/TwDocument.vala | 51 ++++---
gxml/libxml-ChildNodeList.vala | 5 +-
gxml/xlibxml.c | 6 +-
gxml/xlibxml.h | 6 +-
test/GXmlTest.vala | 1 +
test/Makefile.am | 1 +
19 files changed, 169 insertions(+), 351 deletions(-)
---
diff --git a/gxml/Document.vala b/gxml/Document.vala
index 2141b73..4d0d798 100644
--- a/gxml/Document.vala
+++ b/gxml/Document.vala
@@ -73,7 +73,7 @@ public interface GXml.Document : Object, GXml.Node
* Is a matter of you to add as a child to any other
* { link GXml.Node}.
*/
- public abstract GXml.Node create_element (string name);
+ public abstract GXml.Node create_element (string name) throws GLib.Error;
/**
* Creates a new { link GXml.Text}.
*
diff --git a/gxml/GXmlAttribute.vala b/gxml/GXmlAttribute.vala
index 5895e60..4963767 100644
--- a/gxml/GXmlAttribute.vala
+++ b/gxml/GXmlAttribute.vala
@@ -27,10 +27,11 @@ using Gee;
public class GXml.GAttribute : GXml.GNode, GXml.Attribute
{
private Xml.Attr* _attr;
- public GAttribute (Xml.Attr *node)
+ public GAttribute (GDocument doc, Xml.Attr *node)
{
_attr = node;
_node = _attr->parent;
+ _doc = doc;
}
public Namespace @namespace {
owned get {
diff --git a/gxml/GXmlCDATA.vala b/gxml/GXmlCDATA.vala
index 7d91061..61d357d 100644
--- a/gxml/GXmlCDATA.vala
+++ b/gxml/GXmlCDATA.vala
@@ -26,9 +26,15 @@ using Gee;
*/
public class GXml.GCDATA : GXml.GNode, GXml.CDATA
{
- public GCDATA (Xml.Node *node)
+ public GCDATA (GDocument doc, Xml.Node *node)
{
_node = node;
+ _doc = doc;
+ }
+ public override string name {
+ owned get {
+ return "#cdata-section".dup ();
+ }
}
// GXml.CDATA
public string str { owned get { return base.value; } }
diff --git a/gxml/GXmlComment.vala b/gxml/GXmlComment.vala
index 2927b6e..f3fe50f 100644
--- a/gxml/GXmlComment.vala
+++ b/gxml/GXmlComment.vala
@@ -26,9 +26,15 @@ using Gee;
*/
public class GXml.GComment : GXml.GNode, GXml.Comment
{
- public GComment (Xml.Node *node)
+ public GComment (GDocument doc, Xml.Node *node)
{
_node = node;
+ _doc = doc;
+ }
+ public override string name {
+ owned get {
+ return "#comment".dup ();
+ }
}
// GXml.Comment
public string str { owned get { return base.value; } }
diff --git a/gxml/GXmlDocument.vala b/gxml/GXmlDocument.vala
index 62c0892..110829d 100644
--- a/gxml/GXmlDocument.vala
+++ b/gxml/GXmlDocument.vala
@@ -52,15 +52,25 @@ public class GXml.GDocument : GXml.GNode, GXml.Document
this.from_string ((string) b.data, options);
}
- public GDocument.from_string (string str, int options = 0) {
+ public GDocument.from_string (string str, int options = 0) throws GLib.Error {
Xmlx.reset_last_error ();
doc = Xml.Parser.parse_memory (str, (int) str.length);
+ var e = Xmlx.get_last_error ();
+ if (e != null) {
+ var errmsg = "Parser Error for string";
+ string s = libxml2_error_to_string (e);
+ if (s != null)
+ errmsg = ". ";
+ throw new GXml.Error.PARSER (errmsg);
+ }
if (doc == null)
doc = new Xml.Doc ();
}
- public GDocument.from_stream (GLib.InputStream istream) {
+ public GDocument.from_stream (GLib.InputStream istream) throws GLib.Error {
var b = new MemoryOutputStream.resizable ();
b.splice (istream, 0);
+ if (b.data == null)
+ throw new DocumentError.INVALID_DOCUMENT_ERROR ("stream doesn't provide data'");
this.from_string ((string) b.data);
}
public GDocument.from_doc (Xml.Doc doc) { this.doc = doc; }
@@ -74,6 +84,10 @@ public class GXml.GDocument : GXml.GNode, GXml.Document
}
return false;
}
+ // GXml.Node
+ public override Gee.Map<string,GXml.Node> attrs { owned get { return new GHashMapAttr (this, _node); } }
+ public override Gee.BidirList<GXml.Node> children { owned get { return new GListChildren (this, _node); } }
+ public override Gee.List<GXml.Namespace> namespaces { owned get { return new GListNamespaces (this,
_node); } }
public override GXml.Document document { get { return this; } }
// GXml.Document
public bool indent { get; set; default = false; }
@@ -98,264 +112,42 @@ public class GXml.GDocument : GXml.GNode, GXml.Document
GLib.warning ("Document have more than one root GXmlElement. Using first found");
}
}
- return new GElement (r);
+ return new GElement (this, r);
}
}
public GXml.Node create_comment (string text)
{
var c = doc->new_comment (text);
- return new GComment (c);
+ return new GComment (this, c);
}
public GXml.Node create_pi (string target, string data)
{
var pi = doc->new_pi (target, data);
- return new GProcessingInstruction (pi);
+ return new GProcessingInstruction (this, pi);
}
- public GXml.Node create_element (string name)
+ public GXml.Node create_element (string name) throws GLib.Error
{
- var e = doc->new_raw_node (null, name, null);
- return new GElement (e);
+ Xmlx.reset_last_error ();
+ var el = doc->new_raw_node (null, name, null);
+ var e = Xmlx.get_last_error ();
+ if (e != null) {
+ var errmsg = "Parser Error for string";
+ string s = libxml2_error_to_string (e);
+ if (s != null)
+ errmsg = ". ";
+ throw new GXml.Error.PARSER (errmsg);
+ }
+ return new GElement (this, el);
}
public GXml.Node create_text (string text)
{
var t = doc->new_text (text);
- return new GText (t);
+ return new GText (this, 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 ();
- }
- }
- }
+ return new GCDATA (this, cd);
}
public override string to_string ()
{
@@ -364,49 +156,20 @@ public class GXml.GDocument : GXml.GNode, GXml.Document
#endif
Xml.Doc doc = new Xml.Doc ();
Xml.TextWriter tw = Xmlx.new_text_writer_doc (ref doc);
- write_document (tw);
+ TwDocument.write_document (this, 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;
- }
+ public virtual bool save (GLib.Cancellable? cancellable = null)
+ throws GLib.Error
+ {
+ return save_as (file, cancellable);
+ }
+ public virtual bool save_as (GLib.File f, GLib.Cancellable? cancellable = null)
+ throws GLib.Error
+ {
+ return TwDocument.tw_save_as (this, f, cancellable);
+ }
}
diff --git a/gxml/GXmlElement.vala b/gxml/GXmlElement.vala
index 7c3d2e6..0b4ef49 100644
--- a/gxml/GXmlElement.vala
+++ b/gxml/GXmlElement.vala
@@ -26,7 +26,10 @@ using Gee;
*/
public class GXml.GElement : GXml.GNode, GXml.Element
{
- public GElement (Xml.Node *node) { _node = node; }
+ public GElement (GDocument doc, Xml.Node *node) {
+ _node = node;
+ _doc = doc;
+ }
// GXml.Node
public override string value
{
@@ -42,7 +45,7 @@ public class GXml.GElement : GXml.GNode, GXml.Element
}
public GXml.Node get_attr (string name)
{
- return new GAttribute (_node->get_prop (name));
+ return new GAttribute (_doc, _node->get_prop (name));
}
public void normalize () {}
public string content {
diff --git a/gxml/GXmlHashMapAttr.vala b/gxml/GXmlHashMapAttr.vala
index 13db1ce..4dc7d8c 100644
--- a/gxml/GXmlHashMapAttr.vala
+++ b/gxml/GXmlHashMapAttr.vala
@@ -24,17 +24,21 @@ using Gee;
public class GXml.GHashMapAttr : Gee.AbstractMap<string,GXml.Node>
{
+ private GDocument _doc;
private Xml.Node *_node;
- public GHashMapAttr (Xml.Node *node) {
+ public GHashMapAttr (GDocument doc, Xml.Node *node) {
_node = node;
+ _doc = doc;
}
public class Entry : Gee.Map.Entry<string,GXml.Node> {
+ private GXml.GDocument _doc;
private Xml.Attr *_attr;
private GAttribute oattr;
- public Entry (Xml.Attr *attr) {
+ public Entry (GDocument doc, Xml.Attr *attr) {
_attr = attr;
- oattr = new GAttribute (_attr);
+ _doc = doc;
+ oattr = new GAttribute (_doc, _attr);
}
public override string key { get { return _attr->name; } }
public override bool read_only { get { return true; } }
@@ -55,7 +59,7 @@ public class GXml.GHashMapAttr : Gee.AbstractMap<string,GXml.Node>
public override GXml.Node @get (string key) {
if (_node == null) return null;
var p = _node->get_prop (key);
- return new GAttribute (p);
+ return new GAttribute (_doc, p);
}
public override bool has (string key, GXml.Node value) { return has_key (key); }
public override bool has_key (string key) {
@@ -66,7 +70,7 @@ public class GXml.GHashMapAttr : Gee.AbstractMap<string,GXml.Node>
}
return false;
}
- public override Gee.MapIterator<string,GXml.Node> map_iterator () { return new Iterator (_node); }
+ public override Gee.MapIterator<string,GXml.Node> map_iterator () { return new Iterator (_doc, _node); }
public override void @set (string key, GXml.Node value) {
if (_node == null) return;
_node->new_prop (key, value value);
@@ -82,7 +86,7 @@ public class GXml.GHashMapAttr : Gee.AbstractMap<string,GXml.Node>
if (_node == null) return l;
var p = _node->properties;
while (p != null) {
- var e = new Entry (p);
+ var e = new Entry (_doc, p);
l.add (e);
p = p->next;
}
@@ -117,19 +121,21 @@ public class GXml.GHashMapAttr : Gee.AbstractMap<string,GXml.Node>
var l = new ArrayList<GXml.Node> ();
var p = _node->properties;
while (p != null) {
- l.add (new GAttribute (p));
+ l.add (new GAttribute (_doc, p));
p = p->next;
}
return l;
}
}
public class Iterator : Object, MapIterator<string,GXml.Node> {
+ private GXml.GDocument _doc;
private Xml.Node *_node;
private Xml.Attr *_current;
- public Iterator (Xml.Node *node) {
+ public Iterator (GXml.GDocument doc, Xml.Node *node) {
_node = node;
_current = null;
+ _doc = doc;
}
public string get_key () {
@@ -137,7 +143,7 @@ public class GXml.GHashMapAttr : Gee.AbstractMap<string,GXml.Node>
return null;
}
public GXml.Node get_value () {
- return new GAttribute (_current);
+ return new GAttribute (_doc, _current);
}
public bool has_next () {
if (_node->properties == null) return false;
diff --git a/gxml/GXmlListChildren.vala b/gxml/GXmlListChildren.vala
index c10460f..e062404 100644
--- a/gxml/GXmlListChildren.vala
+++ b/gxml/GXmlListChildren.vala
@@ -24,13 +24,15 @@ using Gee;
public class GXml.GListChildren : AbstractBidirList<GXml.Node>
{
+ private GXml.GDocument _doc;
private Xml.Node *_node;
private bool _read_only = false;
- public GListChildren (Xml.Node* node) {
+ public GListChildren (GDocument doc, Xml.Node* node) {
_node = node;
+ _doc = doc;
}
public new override Gee.BidirListIterator<GXml.Node> bidir_list_iterator () {
- return new Iterator (_node);
+ return new Iterator (_doc, _node);
}
// List
public override GXml.Node @get (int index) {
@@ -40,7 +42,7 @@ public class GXml.GListChildren : AbstractBidirList<GXml.Node>
while (n != null) {
var t = (GXml.NodeType) n->type;
if (i == index) {
- return GNode.to_gnode (n);
+ return GNode.to_gnode (_doc, n);
}
i++;
n = n->next;
@@ -63,7 +65,7 @@ public class GXml.GListChildren : AbstractBidirList<GXml.Node>
* 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); }
+ public override Gee.ListIterator<GXml.Node> list_iterator () { return new Iterator (_doc, _node); }
/**
* This method is ignored by default.
*/
@@ -79,7 +81,7 @@ public class GXml.GListChildren : AbstractBidirList<GXml.Node>
int i = 0;
while (n != null) {
if (i >= start && i <= stop) {
- l.add (GNode.to_gnode (n));
+ l.add (GNode.to_gnode (_doc, n));
}
n = n->next;
i++;
@@ -110,7 +112,7 @@ public class GXml.GListChildren : AbstractBidirList<GXml.Node>
}
return false;
}
- public override Gee.Iterator<GXml.Node> iterator () { return new Iterator (_node); }
+ public override Gee.Iterator<GXml.Node> iterator () { return new Iterator (_doc, _node); }
public override bool remove (GXml.Node item) {
if (_node == null) return false;
if (!(item is GXml.GNode)) return false;
@@ -144,12 +146,14 @@ public class GXml.GListChildren : AbstractBidirList<GXml.Node>
Gee.BidirIterator<GXml.Node>,
Gee.ListIterator<GXml.Node>,
BidirListIterator<GXml.Node> {
+ private GDocument _doc;
private Xml.Node *_node;
private Xml.Node *_current;
private int i = 0;
- public Iterator (Xml.Node *node) {
+ public Iterator (GDocument doc, Xml.Node *node) {
_node = node;
_current = _node->children;
+ _doc = doc;
}
/**
* This method is ignored by default.
@@ -166,7 +170,7 @@ public class GXml.GListChildren : AbstractBidirList<GXml.Node>
*/
public new void @set (GXml.Node item) {}
// Iterator
- public new GXml.Node @get () { return GNode.to_gnode (_node); }
+ public new GXml.Node @get () { return GNode.to_gnode (_doc, _node); }
public bool has_next () {
if (_node == null) return false;
if (_node->children == null) return false;
diff --git a/gxml/GXmlListNamespaces.vala b/gxml/GXmlListNamespaces.vala
index 43f8c5e..2484fd1 100644
--- a/gxml/GXmlListNamespaces.vala
+++ b/gxml/GXmlListNamespaces.vala
@@ -24,10 +24,12 @@ using Gee;
public class GXml.GListNamespaces : Gee.AbstractList<GXml.Node>
{
+ private GDocument _doc;
private Xml.Node *_node;
private bool _read_only = false;
- public GListNamespaces (Xml.Node *node) {
+ public GListNamespaces (GDocument doc, Xml.Node *node) {
_node = node;
+ _doc = doc;
}
// List
public override new GXml.Node @get (int index) {
diff --git a/gxml/GXmlNode.vala b/gxml/GXmlNode.vala
index 3b1eff3..f5370cc 100644
--- a/gxml/GXmlNode.vala
+++ b/gxml/GXmlNode.vala
@@ -31,7 +31,7 @@ public abstract class GXml.GNode : Object, GXml.Node
protected Xml.Node *_node;
internal Xml.TextWriter *tw;
- construct { Init.init (); }
+ construct { Init.init (); }
// GXml.Node
public virtual bool set_namespace (string uri, string? prefix)
@@ -39,9 +39,9 @@ public abstract class GXml.GNode : Object, GXml.Node
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 Gee.Map<string,GXml.Node> attrs { owned get { return new GHashMapAttr (_doc, _node); } }
+ public virtual Gee.BidirList<GXml.Node> children { owned get { return new GListChildren (_doc, _node); } }
+ public virtual Gee.List<GXml.Namespace> namespaces { owned get { return new GListNamespaces (_doc, _node);
} }
public virtual GXml.Document document { get { return _doc; } }
public virtual GXml.NodeType type_node {
get {
@@ -69,20 +69,20 @@ public abstract class GXml.GNode : Object, GXml.Node
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) {
+ public static GXml.Node to_gnode (GXml.GDocument doc, Xml.Node *node) {
var t = (GXml.NodeType) node->type;
switch (t) {
case GXml.NodeType.ELEMENT:
- return new GElement (node);
+ return new GElement (doc, node);
break;
case GXml.NodeType.ATTRIBUTE:
- return new GAttribute ((Xml.Attr*) node);
+ return new GAttribute (doc, (Xml.Attr*) node);
break;
case GXml.NodeType.TEXT:
- return new GText (node);
+ return new GText (doc, node);
break;
case GXml.NodeType.CDATA_SECTION:
- return new GCDATA (node);
+ return new GCDATA (doc, node);
break;
case GXml.NodeType.ENTITY_REFERENCE:
return null;
@@ -91,10 +91,10 @@ public abstract class GXml.GNode : Object, GXml.Node
return null;
break;
case GXml.NodeType.PROCESSING_INSTRUCTION:
- return new GProcessingInstruction (node);
+ return new GProcessingInstruction (doc, node);
break;
case GXml.NodeType.COMMENT:
- return new GComment (node);
+ return new GComment (doc, node);
break;
case GXml.NodeType.DOCUMENT:
return new GDocument.from_doc (node->doc);
diff --git a/gxml/GXmlProcessingInstruction.vala b/gxml/GXmlProcessingInstruction.vala
index c7a8711..54e5665 100644
--- a/gxml/GXmlProcessingInstruction.vala
+++ b/gxml/GXmlProcessingInstruction.vala
@@ -26,9 +26,10 @@ using Gee;
*/
public class GXml.GProcessingInstruction : GXml.GNode, GXml.ProcessingInstruction
{
- public GProcessingInstruction (Xml.Node *node)
+ public GProcessingInstruction (GDocument doc, Xml.Node *node)
{
_node = node;
+ _doc = doc;
}
// GXml.ProcessingInstruction
public string target { owned get { return name; } }
diff --git a/gxml/GXmlText.vala b/gxml/GXmlText.vala
index 4c02115..2dc07ab 100644
--- a/gxml/GXmlText.vala
+++ b/gxml/GXmlText.vala
@@ -26,9 +26,15 @@ using Gee;
*/
public class GXml.GText : GXml.GNode, GXml.Text
{
- public GText (Xml.Node *node)
+ public GText (GDocument doc, Xml.Node *node)
{
_node = node;
+ _doc = doc;
+ }
+ public override string name {
+ owned get {
+ return "#text".dup ();
+ }
}
// GXml.Text
public string str { owned get { return base.value; } }
diff --git a/gxml/Node.vala b/gxml/Node.vala
index ca62760..da0a433 100644
--- a/gxml/Node.vala
+++ b/gxml/Node.vala
@@ -83,12 +83,20 @@ public interface GXml.Node : Object
get_elements_by_property_value (string property, string value)
{
var list = new Gee.ArrayList<GXml.Node>();
- foreach (var child in childs) {
+ if (!(this is GXml.Element)) return list;
+ foreach (var child in children) {
+ Test.message ("At node: "+child.name);
list.add_all (child.get_elements_by_property_value (property, value));
if (child is GXml.Element) {
- var cls = (child as GXml.Element).attrs.get (property);
- if (cls == null) continue;
- if (value in ((GXml.Element) child).content)
+ Test.message ("Node is Element: "+child.name);
+ if (child.attrs == null) continue;
+ Test.message ("Searching property: "+property+" in node: "+child.name);
+ var cls = child.attrs.get (property);
+ if (cls == null) {
+ Test.message ("No property :"+ property+" found");
+ continue;
+ }
+ if (value in ((GXml.Element) cls).value)
list.add (child);
}
}
diff --git a/gxml/TwDocument.vala b/gxml/TwDocument.vala
index aca7887..78b8287 100644
--- a/gxml/TwDocument.vala
+++ b/gxml/TwDocument.vala
@@ -97,8 +97,10 @@ public class GXml.TwDocument : GXml.TwNode, GXml.Document
var pi = new TwProcessingInstruction (this, target, data);
return pi;
}
- public GXml.Node create_element (string name)
+ public GXml.Node create_element (string name) throws GLib.Error
{
+ if (Xmlx.validate_name (name, 1) != 0)
+ throw new GXml.Error.PARSER (_("Invalid element name"));
return new TwElement (this, name);
}
public GXml.Node create_text (string text)
@@ -119,45 +121,49 @@ public class GXml.TwDocument : GXml.TwNode, GXml.Document
}
[Deprecated (since="0.8.1", replacement="save_as")]
public bool save_to (GLib.File f, GLib.Cancellable? cancellable = null)
+ throws GLib.Error
{
return save_as (f, cancellable);
}
public bool save_as (GLib.File f, GLib.Cancellable? cancellable = null)
+ throws GLib.Error
+ {
+ return tw_save_as (this, f, cancellable);
+ }
+ public static bool tw_save_as (GXml.Document doc, GLib.File f,
+ GLib.Cancellable? cancellable = null)
+ throws GLib.Error
{
var buf = new Xml.Buffer ();
var tw = Xmlx.new_text_writer_memory (buf, 0);
GLib.Test.message ("Writing down to buffer");
- write_document (tw);
+ write_document (doc, 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;
- }
+ 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, doc.backup, GLib.FileCreateFlags.NONE, cancellable);
+ ostream.splice (b, GLib.OutputStreamSpliceFlags.NONE);
+ ostream.close ();
return true;
}
- public virtual void write_document (Xml.TextWriter tw)
+ public static void write_document (GXml.Document doc, Xml.TextWriter tw)
+ throws GLib.Error
{
tw.start_document ();
- tw.set_indent (indent);
+ tw.set_indent (doc.indent);
// Root
- if (root == null) {
+ if (doc.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);
+ start_node (doc, tw, doc.root, true, ref dns);
#if DEBUG
GLib.message ("Ending writting Document Root node");
#endif
@@ -168,7 +174,10 @@ public class GXml.TwDocument : GXml.TwNode, GXml.Document
tw.end_document ();
tw.flush ();
}
- public virtual void start_node (Xml.TextWriter tw, GXml.Node node, bool root, ref Gee.ArrayList<string>
declared_ns)
+ public static void start_node (GXml.Document doc, Xml.TextWriter tw,
+ GXml.Node node, bool root,
+ ref Gee.ArrayList<string> declared_ns)
+ throws GLib.Error
{
int size = 0;
#if DEBUG
@@ -184,7 +193,7 @@ public class GXml.TwDocument : GXml.TwNode, GXml.Document
if (node.document.namespaces.size > 0) {
var dns = node.document.namespaces.get (0);
assert (dns != null);
- if (prefix_default_ns) {
+ if (doc.prefix_default_ns) {
tw.start_element_ns (dns.prefix, node.name, dns.uri);
declared_ns.add (dns.uri);
#if DEBUG
@@ -309,7 +318,7 @@ public class GXml.TwDocument : GXml.TwNode, GXml.Document
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);
+ start_node (doc, tw, n, false, ref declared_ns);
size += tw.end_element ();
if (size > 1500)
tw.flush ();
@@ -354,7 +363,7 @@ public class GXml.TwDocument : GXml.TwNode, GXml.Document
#endif
Xml.Doc doc = new Xml.Doc ();
Xml.TextWriter tw = Xmlx.new_text_writer_doc (ref doc);
- write_document (tw);
+ write_document (this, tw);
string str;
int size;
doc.dump_memory (out str, out size);
diff --git a/gxml/libxml-ChildNodeList.vala b/gxml/libxml-ChildNodeList.vala
index cb3a8d4..1f4bb94 100644
--- a/gxml/libxml-ChildNodeList.vala
+++ b/gxml/libxml-ChildNodeList.vala
@@ -82,11 +82,12 @@ internal abstract class GXml.ChildNodeList : AbstractBidirList<xNode>, NodeList
{
Xml.Node *cur = head;
int i = 0;
- while (cur->next != null && i != n) {
+ while (cur != null) {
+ if (i == n) return this.owner.lookup_node (cur);
cur = cur->next;
i++;
}
- return this.owner.lookup_node (cur);
+ return null;
}
public override int index_of (xNode item)
requires (item is BackedNode)
diff --git a/gxml/xlibxml.c b/gxml/xlibxml.c
index eac9868..2f57eaa 100644
--- a/gxml/xlibxml.c
+++ b/gxml/xlibxml.c
@@ -27,7 +27,7 @@ void* gxml_doc_get_intsubset_entities (xmlDoc *doc)
return doc->intSubset->entities;
}
-int gxml_validate_name (xmlChar* name, int space)
+gint gxml_validate_name (xmlChar* name, int space)
{
g_return_if_fail (name != NULL);
return xmlValidateName (name, space);
@@ -82,14 +82,14 @@ xmlTextWriterPtr gxml_new_text_writer_memory (xmlBufferPtr buffer, gint compress
return xmlNewTextWriterMemory (buffer, compression);
}
-int gxml_text_writer_write_cdata (xmlTextWriterPtr tw, const xmlChar* text)
+gint gxml_text_writer_write_cdata (xmlTextWriterPtr tw, const xmlChar* text)
{
g_return_if_fail (tw != NULL);
g_return_if_fail (text != NULL);
return xmlTextWriterWriteCDATA (tw, text);
}
-int gxml_text_writer_write_pi (xmlTextWriterPtr tw, const xmlChar* target, const xmlChar* data)
+gint gxml_text_writer_write_pi (xmlTextWriterPtr tw, const xmlChar* target, const xmlChar* data)
{
g_return_if_fail (tw != NULL);
g_return_if_fail (target != NULL);
diff --git a/gxml/xlibxml.h b/gxml/xlibxml.h
index a1431fe..09c5280 100644
--- a/gxml/xlibxml.h
+++ b/gxml/xlibxml.h
@@ -27,7 +27,7 @@
#include <glib.h>
void* gxml_doc_get_intsubset_entities (xmlDoc *doc);
-int gxml_validate_name (xmlChar* name, int space);
+gint gxml_validate_name (xmlChar* name, int space);
xmlErrorPtr gxml_parser_context_get_last_error (void* ctx);
xmlErrorPtr gxml_context_get_last_error (void* ctx);
void gxml_context_reset_last_error (void* ctx);
@@ -36,7 +36,7 @@ void gxml_reset_last_error ();
xmlNsPtr* gxml_doc_get_ns_list (xmlDoc* doc, xmlNode* node);
xmlTextWriterPtr gxml_new_text_writer_doc (xmlDoc** doc);
xmlTextWriterPtr gxml_new_text_writer_memory (xmlBufferPtr buffer, gint compression);
-int gxml_text_writer_write_cdata (xmlTextWriter* tw, const xmlChar* text);
-int gxml_text_writer_write_pi (xmlTextWriter* tw, const xmlChar* target, const xmlChar*
data);
+gint gxml_text_writer_write_cdata (xmlTextWriter* tw, const xmlChar* text);
+gint gxml_text_writer_write_pi (xmlTextWriter* tw, const xmlChar* target, const xmlChar*
data);
#endif
diff --git a/test/GXmlTest.vala b/test/GXmlTest.vala
index fe1aa52..7815542 100644
--- a/test/GXmlTest.vala
+++ b/test/GXmlTest.vala
@@ -83,6 +83,7 @@ class GXmlTest {
SerializablePropertyValueListTest.add_tests ();
SerializablePropertyEnumTest.add_tests ();
GDocumentTest.add_tests ();
+ HtmlDocumentTest.add_tests ();
Test.run ();
diff --git a/test/Makefile.am b/test/Makefile.am
index b82343e..341ee24 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -61,6 +61,7 @@ sources = \
TwCommentTest.vala \
TwProcessingInstructionTest.vala \
GDocumentTest.vala \
+ HtmlDocumentTest.vala \
$(NULL)
gxml_test.vala.stamp: $(sources)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]