[gxml] Improved TwDocument Namespace handling
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gxml] Improved TwDocument Namespace handling
- Date: Wed, 13 May 2015 20:50:32 +0000 (UTC)
commit c872a9ce9603872b6c36ff65dbab671774153039
Author: Daniel Espinosa <esodan gmail com>
Date: Wed May 13 11:02:14 2015 -0500
Improved TwDocument Namespace handling
* By default no prefix are added for default namespace
* Added GXml.Document.prefix_default_ns to add default namespace's
prefix
* By setting a namespace to GXml.Document/TwDocument, first one
is used as default for all document
* Added GXml.Document.ns_top to add all namespaces declarations to
root node (still fails to remove its declaration in children nodes)
gxml/Document.vala | 16 +++
gxml/Node.vala | 2 +-
gxml/TwDocument.vala | 93 ++++++++++-----
gxml/TwNamespace.vala | 2 +-
gxml/TwNode.vala | 2 +-
gxml/libxml-BackedNode.vala | 4 +-
gxml/libxml-Document.vala | 2 +
gxml/libxml-Node.vala | 4 +-
test/SerializableObjectModel-Tw-Test.vala | 4 +-
test/TwElementTest.vala | 181 +++++++++++++++++++++++++++++
test/TwProcessingInstructionTest.vala | 1 -
11 files changed, 272 insertions(+), 39 deletions(-)
---
diff --git a/gxml/Document.vala b/gxml/Document.vala
index 44b63f9..085ddae 100644
--- a/gxml/Document.vala
+++ b/gxml/Document.vala
@@ -39,6 +39,22 @@ public interface GXml.Document : Object, GXml.Node
*/
public abstract bool indent { get; set; }
/**
+ * Controls if writting this documentsshould use namespaces
+ * declaration at root { link GXml.Element}.
+ *
+ * This removes full declaration at childs nodes, because they
+ * are just prefixed if a prefix was defined for namespace apply.
+ */
+ public abstract bool ns_top { get; set; }
+ /**
+ * Controls if writting this document should use default namespace's prefix
+ * to prefix root's childs { link GXml.Element}.
+ *
+ * This removes prefix on childs using default namespace. Default namespace
+ * is the first one found in { link GXml.Node.namespaces} for this document.
+ */
+ public abstract bool prefix_default_ns { get; set; }
+ /**
* XML document root node as a { link GXml.Element}.
*/
public abstract GXml.Node root { get; }
diff --git a/gxml/Node.vala b/gxml/Node.vala
index dc366b9..95bd31e 100644
--- a/gxml/Node.vala
+++ b/gxml/Node.vala
@@ -68,7 +68,7 @@ public interface GXml.Node : Object
* Search for existing document's namespaces and applies it if found or creates
* a new one, appending to document's namespaces collection.
*/
- public abstract bool set_namespace (string uri, string prefix);
+ public abstract bool set_namespace (string uri, string? prefix);
/**
* Node's defaults namespace's prefix.
*
diff --git a/gxml/TwDocument.vala b/gxml/TwDocument.vala
index 0a42017..6c2119c 100644
--- a/gxml/TwDocument.vala
+++ b/gxml/TwDocument.vala
@@ -35,7 +35,7 @@ public class GXml.TwDocument : GXml.TwNode, GXml.Document
this.file = f;
}
// GXml.Node
- public override bool set_namespace (string uri, string prefix)
+ public override bool set_namespace (string uri, string? prefix)
{
_namespaces.add (new TwNamespace (this, uri, prefix));
return true;
@@ -43,6 +43,28 @@ public class GXml.TwDocument : GXml.TwNode, GXml.Document
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 GLib.File file { get; set; }
+ public GXml.Node root {
+ get {
+ if (_root == 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)
+ _root = (GXml.Element) n;
+ }
+ }
+ if (found > 1) {
+ GLib.warning ("Document have more than one root GXmlElement. Using first found");
+ }
+ }
+ return _root;
+ }
+ }
public GXml.Node create_comment (string text)
{
var c = new TwComment (this, text);
@@ -67,26 +89,6 @@ public class GXml.TwDocument : GXml.TwNode, GXml.Document
var t = new TwCDATA (this, text);
return t;
}
- public GLib.File file { get; set; }
- public GXml.Node root {
- get {
- if (_root == 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)
- _root = (GXml.Element) n;
- }
- }
- if (found > 1) {
- GLib.warning ("Document have more than one GXmlElement. Using first found");
- }
- }
- return _root;
- }
- }
public bool save (GLib.Cancellable? cancellable = null)
throws GLib.Error
{
@@ -110,7 +112,7 @@ public class GXml.TwDocument : GXml.TwNode, GXml.Document
#if DEBUG
GLib.message ("Starting writting Document Root node");
#endif
- start_node (tw, root);
+ start_node (tw, root, true);
#if DEBUG
GLib.message ("Ending writting Document Root node");
#endif
@@ -121,7 +123,7 @@ public class GXml.TwDocument : GXml.TwNode, GXml.Document
tw.end_document ();
tw.flush ();
}
- public virtual void start_node (Xml.TextWriter tw, GXml.Node node)
+ public virtual void start_node (Xml.TextWriter tw, GXml.Node node, bool root)
{
int size = 0;
#if DEBUG
@@ -133,16 +135,47 @@ public class GXml.TwDocument : GXml.TwNode, GXml.Document
GLib.message (@"Element Document is Null... '$((node.document == null).to_string ())'");
GLib.message (@"Namespaces in Element... '$(node.namespaces.size)'");
#endif
- if (node.namespaces.size > 0) {
+ 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);
+ else {
+ // Write default namespace no prefix
+ tw.start_element (node.name);
+ if (dns.prefix == null)
+ tw.write_attribute ("xmlns",dns.uri);
+ else
+ tw.write_attribute ("xmlns:"+dns.prefix,dns.uri);
+ }
+ 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);
+ tw.write_attribute ("xmlns:"+ns.prefix, ns.uri);
+ }
+ }
+ }
+ else
+ tw.start_element (node.name);
+ }
+ else {
+ if (node.namespaces.size > 0) {
#if DEBUG
- GLib.message ("Starting Element: start with NS");
+ GLib.message ("Starting Element: start with NS");
#endif
- tw.start_element_ns (node.ns_prefix (), node.name, node.ns_uri ());
- } else {
+ if (node.document.namespaces.first ().uri == node.ns_uri () && !node.document.prefix_default_ns) {
+ // Don't prefix. Using default namespace and prefix_default_ns = false
+ tw.start_element (node.name);
+ }
+ else
+ tw.start_element_ns (node.ns_prefix (), node.name, node.ns_uri ());
+ } else {
#if DEBUG
- GLib.message ("Starting Element: start no NS");
+ GLib.message ("Starting Element: start no NS");
#endif
- tw.start_element (node.name);
+ tw.start_element (node.name);
+ }
}
#if DEBUG
GLib.message ("Starting Element: writting attributes");
@@ -174,7 +207,7 @@ public class GXml.TwDocument : GXml.TwNode, GXml.Document
#if DEBUG
GLib.message (@"Starting Child Element: writting Node '$(n.name)'");
#endif
- start_node (tw, n);
+ start_node (tw, n, false);
size += tw.end_element ();
if (size > 1500)
tw.flush ();
diff --git a/gxml/TwNamespace.vala b/gxml/TwNamespace.vala
index cc987e0..705632c 100644
--- a/gxml/TwNamespace.vala
+++ b/gxml/TwNamespace.vala
@@ -25,7 +25,7 @@ public class GXml.TwNamespace : GXml.TwNode, GXml.Namespace
{
private string _uri = null;
private string _prefix = null;
- public TwNamespace (GXml.Document d, string uri, string prefix)
+ public TwNamespace (GXml.Document d, string uri, string? prefix)
requires (d is TwDocument)
{
_doc = d;
diff --git a/gxml/TwNode.vala b/gxml/TwNode.vala
index 7677a2b..c3c98dd 100644
--- a/gxml/TwNode.vala
+++ b/gxml/TwNode.vala
@@ -32,7 +32,7 @@ public abstract class GXml.TwNode : Object, GXml.Node
internal Xml.TextWriter *tw;
// GXml.Node
- public virtual bool set_namespace (string uri, string prefix)
+ public virtual bool set_namespace (string uri, string? prefix)
{
bool found = false;
foreach (GXml.Namespace ns in document.namespaces) {
diff --git a/gxml/libxml-BackedNode.vala b/gxml/libxml-BackedNode.vala
index e17d1dd..67eeb84 100644
--- a/gxml/libxml-BackedNode.vala
+++ b/gxml/libxml-BackedNode.vala
@@ -89,7 +89,7 @@ namespace GXml {
/**
* { inheritDoc}
*/
- public override NamespaceAttr? add_namespace_attr (string uri, string namespace_prefix)
+ public override NamespaceAttr? add_namespace_attr (string uri, string? namespace_prefix)
{
//stdout.printf ("BackedNode: Before add new Namespace\n");
var ns = this.node->new_ns (uri, namespace_prefix);
@@ -101,7 +101,7 @@ namespace GXml {
/**
* { inheritDoc}
*/
- public override bool set_namespace (string uri, string namespace_prefix)
+ public override bool set_namespace (string uri, string? namespace_prefix)
{
#if DEBUG
GLib.message ("Setting a new Namespace...");
diff --git a/gxml/libxml-Document.vala b/gxml/libxml-Document.vala
index abda0c7..660f584 100644
--- a/gxml/libxml-Document.vala
+++ b/gxml/libxml-Document.vala
@@ -1015,6 +1015,8 @@ namespace GXml {
}
// GXml.Document interface
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 GLib.File file { get; set; }
public virtual GXml.Node root { get { return document_element; } }
public GXml.Node create_text (string str) { return (GXml.Node) this.create_text_node (str); }
diff --git a/gxml/libxml-Node.vala b/gxml/libxml-Node.vala
index f816e1e..63cb3a3 100644
--- a/gxml/libxml-Node.vala
+++ b/gxml/libxml-Node.vala
@@ -114,7 +114,7 @@ namespace GXml {
/**
* Add a new namespace to this { link GXml.xNode}
*/
- public virtual NamespaceAttr? add_namespace_attr (string uri, string namespace_prefix)
+ public virtual NamespaceAttr? add_namespace_attr (string uri, string? namespace_prefix)
{
return null;
}
@@ -124,7 +124,7 @@ namespace GXml {
*
* Returns: { link true} if namespace exists.
*/
- public virtual bool set_namespace (string uri, string namespace_prefix)
+ public virtual bool set_namespace (string uri, string? namespace_prefix)
{
return false;
}
diff --git a/test/SerializableObjectModel-Tw-Test.vala b/test/SerializableObjectModel-Tw-Test.vala
index 735a0ee..fd1aee0 100644
--- a/test/SerializableObjectModel-Tw-Test.vala
+++ b/test/SerializableObjectModel-Tw-Test.vala
@@ -288,7 +288,9 @@ class SerializableObjectModelTwTest : GXmlTest
var doc = new TwDocument ();
ns.serialize (doc);
string str = doc.to_string ();
- assert ("<gxml:namespace xmlns:gxml=\"http://www.gnome.org/GXml\"/>" in str);
+#if DEBUG
+ GLib.message (@"$doc");
+ assert ("<namespace xmlns:gxml=\"http://www.gnome.org/GXml\"/>" in str);
} catch (GLib.Error e) {
#if DEBUG
GLib.message ("ERROR: "+e.message);
diff --git a/test/TwElementTest.vala b/test/TwElementTest.vala
index c333eed..4cf4c86 100644
--- a/test/TwElementTest.vala
+++ b/test/TwElementTest.vala
@@ -95,5 +95,186 @@ class TwElementTest : GXmlTest {
e.content = null;
assert (e.childs.size == 1);
});
+ Test.add_func ("/gxml/tw-element/namespaces/default", () => {
+ var d = new TwDocument ();
+ var r = d.create_element ("root");
+ d.childs.add (r);
+ // Set default namespace
+ d.set_namespace ("http://www.gnome.org/gxml", null);
+ var e = d.create_element ("child");
+ r.childs.add (e);
+ assert (d.namespaces.size == 1);
+ string str = d.to_string ();
+#if DEBUG
+ GLib.message (@"$d");
+#endif
+ assert ("<root xmlns=\"http://www.gnome.org/gxml\">" in str);
+ });
+ Test.add_func ("/gxml/tw-element/namespaces/default-prefix", () => {
+ var d = new TwDocument ();
+ var r = d.create_element ("root");
+ d.childs.add (r);
+ // Set default namespace
+ d.set_namespace ("http://www.gnome.org/gxml", "gxml");
+ var e = d.create_element ("child");
+ r.childs.add (e);
+ assert (d.namespaces.size == 1);
+ string str = d.to_string ();
+#if DEBUG
+ GLib.message (@"$d");
+#endif
+ assert ("<root xmlns:gxml=\"http://www.gnome.org/gxml\">" in str);
+ });
+ Test.add_func ("/gxml/tw-element/namespaces/default-prefix-null", () => {
+ var d = new TwDocument ();
+ var r = d.create_element ("root");
+ d.childs.add (r);
+ // Set default namespace
+ d.set_namespace ("http://www.gnome.org/gxml", null);
+ var e = d.create_element ("child");
+ r.childs.add (e);
+ assert (d.namespaces.size == 1);
+ string str = d.to_string ();
+#if DEBUG
+ GLib.message (@"$d");
+#endif
+ assert ("<root xmlns=\"http://www.gnome.org/gxml\">" in str);
+ });
+ Test.add_func ("/gxml/tw-element/namespaces/default/enable-prefix_default_ns", () => {
+ var d = new TwDocument ();
+ var r = d.create_element ("root");
+ d.childs.add (r);
+ // Set default namespace
+ d.set_namespace ("http://www.gnome.org/gxml", "gxml");
+ d.prefix_default_ns = true;
+ var e = d.create_element ("child");
+ r.childs.add (e);
+ assert (d.namespaces.size == 1);
+ string str = d.to_string ();
+#if DEBUG
+ GLib.message (@"$d");
+#endif
+ assert ("<gxml:root xmlns:gxml=\"http://www.gnome.org/gxml\">" in str);
+ });
+ Test.add_func ("/gxml/tw-element/multiple-namespaces", () => {
+ var d = new TwDocument ();
+ var r = d.create_element ("root");
+ d.childs.add (r);
+ r.set_namespace ("http://git.gnome.org/browse/gxml", "gxml");
+ var e = d.create_element ("child");
+ r.childs.add (e);
+ assert (r.namespaces.size == 1);
+ assert (d.namespaces.size == 1);
+ e.set_namespace ("http://developer.gnome.org/", "dg");
+ assert (e.namespaces.size == 1);
+ assert (r.namespaces.size == 1);
+ assert (d.namespaces.size == 2);
+ var e2 = d.create_element ("nons");
+ e.childs.add (e2);
+ e2.set_namespace ("http://www.gnome.org/", null);
+ assert (e.namespaces.size == 1);
+ assert (r.namespaces.size == 1);
+ assert (e2.namespaces.size == 1);
+ assert (d.namespaces.size == 3);
+ string str = d.to_string ();
+#if DEBUG
+ GLib.message (@"$d");
+#endif
+ assert ("<root xmlns:gxml=\"http://git.gnome.org/browse/gxml\">" in str);
+ assert ("</root>" in str);
+ assert ("<dg:child xmlns:dg=\"http://developer.gnome.org/\">" in str);
+ assert ("<nons xmlns=\"http://www.gnome.org/\"/>" in str);
+ });
+ Test.add_func ("/gxml/tw-element/multiple-namespaces/default", () => {
+ var d = new TwDocument ();
+ var r = d.create_element ("root");
+ d.childs.add (r);
+ // Default NS
+ d.set_namespace ("http://git.gnome.org/browse/gxml", null);
+ var e = d.create_element ("child");
+ r.childs.add (e);
+ assert (d.namespaces.size == 1);
+ e.set_namespace ("http://developer.gnome.org/", "dg");
+ assert (e.namespaces.size == 1);
+ assert (d.namespaces.size == 2);
+ var e2 = d.create_element ("children");
+ e.childs.add (e2);
+ assert (e.namespaces.size == 1);
+ assert (e2.namespaces.size == 0);
+ assert (d.namespaces.size == 2);
+ var e3 = d.create_element ("nons");
+ e.childs.add (e3);
+ e3.set_namespace ("http://www.gnome.org/", "ns");
+ assert (e.namespaces.size == 1);
+ assert (e2.namespaces.size == 0);
+ assert (e3.namespaces.size == 1);
+ assert (d.namespaces.size == 3);
+ var e4 = d.create_element ("childrenons");
+ e3.childs.add (e4);
+ assert (e.namespaces.size == 1);
+ assert (e2.namespaces.size == 0);
+ assert (e3.namespaces.size == 1);
+ assert (e4.namespaces.size == 0);
+ assert (d.namespaces.size == 3);
+ string str = d.to_string ();
+#if DEBUG
+ GLib.message (@"$d");
+#endif
+ assert ("<root xmlns=\"http://git.gnome.org/browse/gxml\">" in str);
+ assert ("</root>" in str);
+ assert ("<dg:child xmlns:dg=\"http://developer.gnome.org/\">" in str);
+ assert ("<children/>" in str);
+ assert ("<ns:nons xmlns:ns=\"http://www.gnome.org/\">" in str);
+ assert ("<childrenons/>" in str);
+ assert ("</ns:nons>" in str);
+ assert ("</dg:child>" in str);
+ });/*
+ Test.add_func ("/gxml/tw-element/multiple-namespaces/default/enable-ns_top", () => {
+ var d = new TwDocument ();
+ var r = d.create_element ("root");
+ d.childs.add (r);
+ // Default NS
+ d.set_namespace ("http://git.gnome.org/browse/gxml", null);
+ // All namespaces declaration should be on root node
+ d.ns_top = true;
+ var e = d.create_element ("child");
+ r.childs.add (e);
+ assert (d.namespaces.size == 1);
+ e.set_namespace ("http://developer.gnome.org/", "dg");
+ assert (e.namespaces.size == 1);
+ assert (d.namespaces.size == 2);
+ var e2 = d.create_element ("children");
+ e.childs.add (e2);
+ assert (e.namespaces.size == 1);
+ assert (e2.namespaces.size == 0);
+ assert (d.namespaces.size == 2);
+ var e3 = d.create_element ("nons");
+ e.childs.add (e3);
+ e3.set_namespace ("http://www.gnome.org/", "ns");
+ assert (e.namespaces.size == 1);
+ assert (e2.namespaces.size == 0);
+ assert (e3.namespaces.size == 1);
+ assert (d.namespaces.size == 3);
+ var e4 = d.create_element ("childrenons");
+ e3.childs.add (e4);
+ assert (e.namespaces.size == 1);
+ assert (e2.namespaces.size == 0);
+ assert (e3.namespaces.size == 1);
+ assert (e4.namespaces.size == 0);
+ assert (d.namespaces.size == 3);
+ string str = d.to_string ();
+#if DEBUG
+ GLib.message (@"$d");
+#endif
+ assert_not_reached ();
+ assert ("<root xmlns=\"http://git.gnome.org/browse/gxml\"
xmlns:dg=\"http://developer.gnome.org/\" xmlns:ns=\"http://www.gnome.org/\">" in str);
+ assert ("</root>" in str);
+ assert ("<dg:child>" in str);
+ assert ("<children/>" in str);
+ assert ("<ns:nons >" in str);
+ assert ("<childrenons/>" in str);
+ assert ("</ns:nons>" in str);
+ assert ("</dg:child>" in str);
+ });*/
}
}
diff --git a/test/TwProcessingInstructionTest.vala b/test/TwProcessingInstructionTest.vala
index e9eb7ec..c154f47 100644
--- a/test/TwProcessingInstructionTest.vala
+++ b/test/TwProcessingInstructionTest.vala
@@ -34,7 +34,6 @@ class TwProcessingInstructionTest : GXmlTest {
assert (pi.value == "transform");
d.root.childs.add (pi);
assert (d.root.childs.size == 1);
- GLib.message (@"Document created: $d");
string str = d.to_string ();
assert ("<root><?xslt transform?></root>" in str);
#if DEBUG
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]