Commit 28c791f6 authored by Paul Warren's avatar Paul Warren
Browse files

XML utilities: moving from private to public repository.

parents
xml @ 77daa6c4
Subproject commit 77daa6c4215addc402666fff17610e3fc1a55f22
package qname
import (
"code.blinkace.com/go/xml/encoding/xml"
"errors"
"sort"
"strings"
)
type QName struct {
Namespace string
Localname string
}
type QNames []QName
func NewFromString(nsMappings map[string]string, qs string) (QName, error) {
var q QName
i := strings.Index(qs, ":")
prefix := ""
if i >= 0 {
prefix = qs[:i]
q.Localname = qs[i+1:]
} else {
q.Localname = qs
}
var ok bool
q.Namespace, ok = nsMappings[prefix]
if !ok {
return q, errors.New("Unbound namespace prefix: " + prefix)
}
return q, nil
}
func (qname *QName) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var s string
d.DecodeElement(&s, &start)
i := strings.Index(s, ":")
prefix := ""
if i >= 0 {
prefix = s[:i]
qname.Localname = s[i+1:]
} else {
qname.Localname = s
}
var ok bool
qname.Namespace, ok = d.NamespaceBindings()[prefix]
if !ok {
if prefix == "" {
qname.Namespace = ""
} else {
return errors.New("Unbound namespace prefix: " + prefix)
}
}
return nil
}
/*
* We can't define UnmarshallXMLAttr for QName because, we don't get given the
* decoder.
*/
func UnmarshallQNameAttr(d *xml.Decoder, s xml.StartElement, a QName) (QName, error) {
var q QName
var err error
for _, x := range s.Attr {
if x.Name.Space == a.Namespace && x.Name.Local == a.Localname {
q, err = NewFromString(d.NamespaceBindings(), x.Value)
if err != nil {
return q, err
}
return q, nil
}
}
return q, nil
}
func (qname QName) String() string {
return "{" + qname.Namespace + "}" + qname.Localname
}
func (qname QName) Equals(cmp QName) bool {
return qname.Namespace == cmp.Namespace && qname.Localname == cmp.Localname
}
func (qq QNames) Len() int {
return len(qq)
}
func (qq QNames) Less(i, j int) bool {
return qq[i].String() < qq[j].String()
}
func (qq QNames) Swap(i, j int) {
qq[i], qq[j] = qq[j], qq[i]
}
func (qq QNames) Equals(cmp QNames) bool {
sort.Sort(qq)
sort.Sort(cmp)
if len(qq) != len(cmp) {
return false
}
for i, _ := range qq {
if !qq[i].Equals(cmp[i]) {
return false
}
}
return true
}
package qname
import (
"fmt"
"testing"
)
func TestQNamesEquals(t *testing.T) {
qa := QNames{
QName{"http://foo.com/", "bar"},
QName{"http://wibble.com/", "blort"},
}
qb := make(QNames, 2)
copy(qb, qa)
if !qa.Equals(qb) {
t.Error("QName lists not equal")
}
qb[0], qb[1] = qb[1], qb[0]
if !qa.Equals(qb) {
t.Error("QName lists not equal")
fmt.Println(qa)
fmt.Println(qb)
}
qc := append(qb, QName{"http://fish.com/", "bar"})
if qc.Equals(qb) {
t.Error("QName lists unexpectedly equal")
}
qd := make(QNames, 2)
copy(qd, qa)
qd[0] = QName{"http://fish.com/", "bar"}
if qd.Equals(qa) {
t.Error("QName lists unexpectedly equal")
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment