Add wildcard support for node names. Allows selecting of all child nodes with a specific namespace (See issue #4).

This commit is contained in:
jim teeuwen 2011-07-13 05:17:00 +02:00
parent 29e84b1aeb
commit 2a2a591c08
5 changed files with 46 additions and 10 deletions

4
README
View File

@ -96,5 +96,7 @@
The namespace name specified in the functions above must either match the The namespace name specified in the functions above must either match the
namespace you expect a node/attr to have, or you can specify a wildcard "*". namespace you expect a node/attr to have, or you can specify a wildcard "*".
This makes node searches easier in case you do not care what namespace name This makes node searches easier in case you do not care what namespace name
there is or if there is one at all. there is or if there is one at all. Node and attribute names as well, may
be supplied as the wildcard "*". This allows us to fetch all child nodes for
a given namespace, regardless of their names.

16
node.go
View File

@ -196,10 +196,15 @@ func (this *Node) Ab(namespace, name string) bool {
// Returns true if this node has the specified attribute. False otherwise. // Returns true if this node has the specified attribute. False otherwise.
func (this *Node) HasAttr(namespace, name string) bool { func (this *Node) HasAttr(namespace, name string) bool {
for _, v := range this.Attributes { for _, v := range this.Attributes {
if (namespace == "*" || namespace == v.Name.Space) && name == v.Name.Local { if namespace != "*" && namespace != v.Name.Space {
continue
}
if name == "*" || name == v.Name.Local {
return true return true
} }
} }
return false return false
} }
@ -209,9 +214,7 @@ func (this *Node) SelectNode(namespace, name string) *Node {
} }
func rec_SelectNode(cn *Node, namespace, name string) *Node { func rec_SelectNode(cn *Node, namespace, name string) *Node {
// Allow wildcard for namespace names. Meaning we will match any namespace if (namespace == "*" || cn.Name.Space == namespace) && (name == "*" || cn.Name.Local == name) {
// name with a matching local name.
if (namespace == "*" || cn.Name.Space == namespace) && cn.Name.Local == name {
return cn return cn
} }
@ -221,6 +224,7 @@ func rec_SelectNode(cn *Node, namespace, name string) *Node {
return tn return tn
} }
} }
return nil return nil
} }
@ -232,9 +236,7 @@ func (this *Node) SelectNodes(namespace, name string) []*Node {
} }
func rec_SelectNodes(cn *Node, namespace, name string, list *[]*Node) { func rec_SelectNodes(cn *Node, namespace, name string, list *[]*Node) {
// Allow wildcard for namespace names. Meaning we will match any namespace if (namespace == "*" || cn.Name.Space == namespace) && (name == "*" || cn.Name.Local == name) {
// name with a matching local name.
if (namespace == "*" || cn.Name.Space == namespace) && cn.Name.Local == name {
*list = append(*list, cn) *list = append(*list, cn)
return return
} }

View File

@ -1 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="0.91"><channel><title>WriteTheWeb</title><link>http://writetheweb.com</link><description>News for web users that write back</description><language>en-us</language><copyright>Copyright 2000, WriteTheWeb team.</copyright><managingEditor>editor@writetheweb.com</managingEditor><webMaster>webmaster@writetheweb.com</webMaster><image><title>WriteTheWeb</title><url>http://writetheweb.com/images/mynetscape88.gif</url><link>http://writetheweb.com</link><width>88</width><height>31</height><description>News for web users that write back</description></image><item><title>Giving the world a pluggable Gnutella</title><link>http://writetheweb.com/read.php?item=24</link><description>WorldOS is a framework on which to build programs that work like Freenet or Gnutella -allowing distributed applications using peer-to-peer routing.</description></item><item><title>Syndication discussions hot up</title><link>http://writetheweb.com/read.php?item=23</link><description>After a period of dormancy, the Syndication mailing list has become active again, with contributions from leaders in traditional media and Web syndication.</description></item><item><title>Personal web server integrates file sharing and messaging</title><link>http://writetheweb.com/read.php?item=22</link><description>The Magi Project is an innovative project to create a combined personal web server and messaging system that enables the sharing and synchronization of information across desktop, laptop and palmtop devices.</description></item><item><title>Syndication and Metadata</title><link>http://writetheweb.com/read.php?item=21</link><description>RSS is probably the best known metadata format around. RDF is probably one of the least understood. In this essay, published on my O'Reilly Network weblog, I argue that the next generation of RSS should be based on RDF.</description></item><item><title>UK bloggers get organised</title><link>http://writetheweb.com/read.php?item=20</link><description>Looks like the weblogs scene is gathering pace beyond the shores of the US. There's now a UK-specific page on weblogs.com, and a mailing list at egroups.</description></item><item><title>Yournamehere.com more important than anything</title><link>http://writetheweb.com/read.php?item=19</link><description>Whatever you're publishing on the web, your site name is the most valuable asset you have, according to Carl Steadman.</description></item></channel></rss>

17
test2.xml Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0"?>
<xml>
<books>
<book>
<xdc:author>moo</xdc:author>
<xdc:price>123</xdc:price>
<xdc:pages>321</xdc:pages>
<xdc:date>1/1/2011</xdc:date>
</book>
<book>
<xdc:author>moo</xdc:author>
<xdc:price>123</xdc:price>
<xdc:pages>321</xdc:pages>
<xdc:date>1/1/2011</xdc:date>
</book>
</books>
</xml>

View File

@ -20,7 +20,23 @@ func TestLoadLocal(t *testing.T) {
} }
} }
func TestLoadRemote(t *testing.T) { func TestWildcard(t *testing.T) {
doc := New()
if err := doc.LoadFile("test2.xml"); err != nil {
t.Error(err.String())
return
}
list := doc.SelectNodes("xdc", "*")
if len(list) != 8 {
t.Errorf("Wrong number of child elements. Expected 4, got %d.", len(list))
return
}
}
func _TestLoadRemote(t *testing.T) {
doc := New() doc := New()
if err := doc.LoadUri("http://blog.golang.org/feeds/posts/default"); err != nil { if err := doc.LoadUri("http://blog.golang.org/feeds/posts/default"); err != nil {