From 0459b7b32edef6fde79e459523f47e8af19c7ace Mon Sep 17 00:00:00 2001 From: Rodrigo Damazio Date: Sun, 29 Jul 2012 16:28:03 -0300 Subject: [PATCH] Making the recursive SelectNodes a separate function and adding tests --- document.go | 14 +++++++++++++- node.go | 16 +++++++++++++--- xmlx_test.go | 18 +++++++++++++++++- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/document.go b/document.go index 2d454ff..1cade3c 100644 --- a/document.go +++ b/document.go @@ -15,9 +15,12 @@ *xmlx.Document.SelectNode(namespace, name string) *Node; *xmlx.Document.SelectNodes(namespace, name string) []*Node; + *xmlx.Document.SelectNodesRecursive(namespace, name string) []*Node; SelectNode() returns the first, single node it finds matching the given name - and namespace. SelectNodes() returns a slice containing all the matching nodes. + and namespace. SelectNodes() returns a slice containing all the matching nodes + (without recursing into matching nodes). SelectNodesRecursive() returns a slice + of all matching nodes, including nodes inside other matching nodes. Note that these search functions can be invoked on individual nodes as well. This allows you to search only a subset of the entire document. @@ -77,10 +80,19 @@ func (this *Document) SelectNode(namespace, name string) *Node { // Select all nodes with the given namespace and name. Returns an empty slice // if no matches were found. +// Select all nodes with the given namespace and name, without recursing +// into the children of those matches. Returns an empty slice if no matching +// node was found. func (this *Document) SelectNodes(namespace, name string) []*Node { return this.Root.SelectNodes(namespace, name) } +// Select all nodes with the given namespace and name, also recursing into the +// children of those matches. Returns an empty slice if no matches were found. +func (this *Document) SelectNodesRecursive(namespace, name string) []*Node { + return this.Root.SelectNodesRecursive(namespace, name) +} + // Load the contents of this document from the supplied reader. func (this *Document) LoadStream(r io.Reader, charset CharsetFunc) (err error) { xp := xml.NewDecoder(r) diff --git a/node.go b/node.go index 715107a..e20181a 100644 --- a/node.go +++ b/node.go @@ -230,17 +230,27 @@ func rec_SelectNode(cn *Node, namespace, name string) *Node { // Select multiple nodes by name func (this *Node) SelectNodes(namespace, name string) []*Node { list := make([]*Node, 0, 16) - rec_SelectNodes(this, namespace, name, &list) + rec_SelectNodes(this, namespace, name, &list, false) return list } -func rec_SelectNodes(cn *Node, namespace, name string, list *[]*Node) { +// Select multiple nodes by name +func (this *Node) SelectNodesRecursive(namespace, name string) []*Node { + list := make([]*Node, 0, 16) + rec_SelectNodes(this, namespace, name, &list, true) + return list +} + +func rec_SelectNodes(cn *Node, namespace, name string, list *[]*Node, recurse bool) { if (namespace == "*" || cn.Name.Space == namespace) && (name == "*" || cn.Name.Local == name) { *list = append(*list, cn) + if !recurse { + return + } } for _, v := range cn.Children { - rec_SelectNodes(v, namespace, name, list) + rec_SelectNodes(v, namespace, name, list, recurse) } } diff --git a/xmlx_test.go b/xmlx_test.go index ef507bf..8a3414a 100644 --- a/xmlx_test.go +++ b/xmlx_test.go @@ -31,7 +31,23 @@ func TestWildcard(t *testing.T) { list := doc.SelectNodes("ns", "*") if len(list) != 1 { - t.Errorf("Wrong number of child elements. Expected 4, got %d.", len(list)) + t.Errorf("Wrong number of child elements. Expected 1, got %d.", len(list)) + return + } +} + +func TestWildcardRecursive(t *testing.T) { + doc := New() + + if err := doc.LoadFile("test2.xml", nil); err != nil { + t.Error(err.Error()) + return + } + + list := doc.SelectNodesRecursive("ns", "*") + + if len(list) != 7 { + t.Errorf("Wrong number of child elements. Expected 7, got %d.", len(list)) return } }