Merge pull request #6 from rdamazio/master

Fixed recursive node selection
This commit is contained in:
jimt 2012-07-29 14:57:44 -07:00
commit 88d4341915
3 changed files with 43 additions and 6 deletions

View File

@ -15,9 +15,12 @@
*xmlx.Document.SelectNode(namespace, name string) *Node; *xmlx.Document.SelectNode(namespace, name string) *Node;
*xmlx.Document.SelectNodes(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 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. 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. 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 // Select all nodes with the given namespace and name. Returns an empty slice
// if no matches were found. // 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 { func (this *Document) SelectNodes(namespace, name string) []*Node {
return this.Root.SelectNodes(namespace, name) 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. // Load the contents of this document from the supplied reader.
func (this *Document) LoadStream(r io.Reader, charset CharsetFunc) (err error) { func (this *Document) LoadStream(r io.Reader, charset CharsetFunc) (err error) {
xp := xml.NewDecoder(r) xp := xml.NewDecoder(r)

15
node.go
View File

@ -230,18 +230,27 @@ func rec_SelectNode(cn *Node, namespace, name string) *Node {
// Select multiple nodes by name // Select multiple nodes by name
func (this *Node) SelectNodes(namespace, name string) []*Node { func (this *Node) SelectNodes(namespace, name string) []*Node {
list := make([]*Node, 0, 16) list := make([]*Node, 0, 16)
rec_SelectNodes(this, namespace, name, &list) rec_SelectNodes(this, namespace, name, &list, false)
return list 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) { if (namespace == "*" || cn.Name.Space == namespace) && (name == "*" || cn.Name.Local == name) {
*list = append(*list, cn) *list = append(*list, cn)
if !recurse {
return return
} }
}
for _, v := range cn.Children { for _, v := range cn.Children {
rec_SelectNodes(v, namespace, name, list) rec_SelectNodes(v, namespace, name, list, recurse)
} }
} }

View File

@ -31,7 +31,23 @@ func TestWildcard(t *testing.T) {
list := doc.SelectNodes("ns", "*") list := doc.SelectNodes("ns", "*")
if len(list) != 1 { 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 return
} }
} }