fixed some slice copy routines

This commit is contained in:
jim teeuwen 2010-05-06 05:36:48 +02:00
parent 379dfddd5b
commit 6a776b0cda
5 changed files with 602 additions and 558 deletions

View File

@ -35,13 +35,13 @@ import "fmt"
import "http" import "http"
type Document struct { type Document struct {
Version string; Version string
Encoding string; Encoding string
StandAlone string; StandAlone string
SaveDocType bool; SaveDocType bool
Root *Node; Root *Node
Entity map[string]string; Entity map[string]string
Verbose bool; Verbose bool
} }
func New() *Document { func New() *Document {
@ -51,7 +51,7 @@ func New() *Document {
StandAlone: "yes", StandAlone: "yes",
SaveDocType: true, SaveDocType: true,
Entity: make(map[string]string), Entity: make(map[string]string),
Verbose: false Verbose: false,
} }
} }
@ -60,88 +60,86 @@ func New() *Document {
// set only those entities needed manually using the document.Entity map, but // set only those entities needed manually using the document.Entity map, but
// if need be, this method can be called to fill the map with the entire set // if need be, this method can be called to fill the map with the entire set
// defined on http://www.w3.org/TR/html4/sgml/entities.html // defined on http://www.w3.org/TR/html4/sgml/entities.html
func (this *Document) LoadExtendedEntityMap() { func (this *Document) LoadExtendedEntityMap() { loadNonStandardEntities(&this.Entity) }
loadNonStandardEntities(&this.Entity);
}
func (this *Document) String() string { func (this *Document) String() string {
s, _ := this.SaveString(); s, _ := this.SaveString()
return s; return s
} }
func (this *Document) SelectNode(namespace, name string) *Node { func (this *Document) SelectNode(namespace, name string) *Node {
return this.Root.SelectNode(namespace, name); return this.Root.SelectNode(namespace, name)
} }
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)
} }
// ***************************************************************************** // *****************************************************************************
// *** Satisfy ILoader interface // *** Satisfy ILoader interface
// ***************************************************************************** // *****************************************************************************
func (this *Document) LoadString(s string) (err os.Error) { func (this *Document) LoadString(s string) (err os.Error) {
xp := xml.NewParser(strings.NewReader(s)); xp := xml.NewParser(strings.NewReader(s))
xp.Entity = this.Entity; xp.Entity = this.Entity
this.Root = NewNode(NT_ROOT); this.Root = NewNode(NT_ROOT)
ct := this.Root; ct := this.Root
for { for {
tok, err := xp.Token(); tok, err := xp.Token()
if err != nil { if err != nil {
if err != os.EOF && this.Verbose { if err != os.EOF && this.Verbose {
fmt.Fprintf(os.Stderr, "Xml Error: %s\n", err); fmt.Fprintf(os.Stderr, "Xml Error: %s\n", err)
} }
return return
} }
t1, ok := tok.(xml.SyntaxError); t1, ok := tok.(xml.SyntaxError)
if ok { if ok {
err = os.NewError(t1.String()); err = os.NewError(t1.String())
return return
} }
t2, ok := tok.(xml.CharData); t2, ok := tok.(xml.CharData)
if ok && ct != nil { if ok && ct != nil {
ct.Value = strings.TrimSpace(string(t2)); ct.Value = strings.TrimSpace(string(t2))
continue continue
} }
t3, ok := tok.(xml.Comment); t3, ok := tok.(xml.Comment)
if ok && ct != nil { if ok && ct != nil {
t := NewNode(NT_COMMENT); t := NewNode(NT_COMMENT)
t.Value = strings.TrimSpace(string(t3)); t.Value = strings.TrimSpace(string(t3))
ct.AddChild(t); ct.AddChild(t)
continue continue
} }
t4, ok := tok.(xml.Directive); t4, ok := tok.(xml.Directive)
if ok && ct != nil { if ok && ct != nil {
t := NewNode(NT_DIRECTIVE); t := NewNode(NT_DIRECTIVE)
t.Value = strings.TrimSpace(string(t4)); t.Value = strings.TrimSpace(string(t4))
ct.AddChild(t); ct.AddChild(t)
continue continue
} }
t5, ok := tok.(xml.StartElement); t5, ok := tok.(xml.StartElement)
if ok && ct != nil { if ok && ct != nil {
t := NewNode(NT_ELEMENT); t := NewNode(NT_ELEMENT)
t.Name = t5.Name; t.Name = t5.Name
t.Attributes = make([]Attr, len(t5.Attr)); t.Attributes = make([]Attr, len(t5.Attr))
for i, v := range t5.Attr { for i, v := range t5.Attr {
t.Attributes[i].Name = v.Name; t.Attributes[i].Name = v.Name
t.Attributes[i].Value = v.Value; t.Attributes[i].Value = v.Value
} }
ct.AddChild(t); ct.AddChild(t)
ct = t; ct = t
continue continue
} }
t6, ok := tok.(xml.ProcInst); t6, ok := tok.(xml.ProcInst)
if ok { if ok {
if t6.Target == "xml" { // xml doctype if t6.Target == "xml" { // xml doctype
doctype := strings.TrimSpace(string(t6.Inst)); doctype := strings.TrimSpace(string(t6.Inst))
/* // Not needed. There is only xml version 1.0 /* // Not needed. There is only xml version 1.0
pos := strings.Index(doctype, `version="`); pos := strings.Index(doctype, `version="`);
@ -162,100 +160,106 @@ func (this *Document) LoadString(s string) (err os.Error) {
} }
*/ */
pos := strings.Index(doctype, `standalone="`); pos := strings.Index(doctype, `standalone="`)
if pos > -1 { if pos > -1 {
this.StandAlone = doctype[pos+len(`standalone="`) : len(doctype)]; this.StandAlone = doctype[pos+len(`standalone="`) : len(doctype)]
pos = strings.Index(this.StandAlone, `"`); pos = strings.Index(this.StandAlone, `"`)
this.StandAlone = this.StandAlone[0:pos]; this.StandAlone = this.StandAlone[0:pos]
} }
} else if ct != nil { } else if ct != nil {
t := NewNode(NT_PROCINST); t := NewNode(NT_PROCINST)
t.Target = strings.TrimSpace(t6.Target); t.Target = strings.TrimSpace(t6.Target)
t.Value = strings.TrimSpace(string(t6.Inst)); t.Value = strings.TrimSpace(string(t6.Inst))
ct.AddChild(t); ct.AddChild(t)
} }
continue continue
} }
_, ok = tok.(xml.EndElement); _, ok = tok.(xml.EndElement)
if ok { if ok {
ct = ct.Parent; ct = ct.Parent
continue continue
} }
} }
return; return
} }
func (this *Document) LoadFile(path string) (err os.Error) { func (this *Document) LoadFile(path string) (err os.Error) {
file, err := os.Open(path, os.O_RDONLY, 0600); file, err := os.Open(path, os.O_RDONLY, 0600)
if err != nil { if err != nil {
return return
} }
defer file.Close(); defer file.Close()
content := ""; content := ""
buff := make([]byte, 256); buff := make([]byte, 256)
for { for {
_, err := file.Read(buff); _, err := file.Read(buff)
if err != nil { if err != nil {
break break
} }
content += string(buff); content += string(buff)
} }
err = this.LoadString(content); err = this.LoadString(content)
return; return
} }
func (this *Document) LoadUri(uri string) (err os.Error) { func (this *Document) LoadUri(uri string) (err os.Error) {
r, _, err := http.Get(uri); r, _, err := http.Get(uri)
if err != nil { if err != nil {
return return
} }
defer r.Body.Close(); defer r.Body.Close()
b, err := io.ReadAll(r.Body); data := ""
if err != nil { b := make([]byte, 256)
return
for {
n, err := io.ReadFull(r.Body, b)
if n == 0 || err == os.EOF {
break
}
data += string(b)
} }
err = this.LoadString(string(b)); err = this.LoadString(data)
return; return
} }
func (this *Document) LoadStream(r *io.Reader) (err os.Error) { func (this *Document) LoadStream(r *io.Reader) (err os.Error) {
content := ""; content := ""
buff := make([]byte, 256); buff := make([]byte, 256)
for { for {
_, err := r.Read(buff); _, err := r.Read(buff)
if err != nil { if err != nil {
break break
} }
content += string(buff); content += string(buff)
} }
err = this.LoadString(content); err = this.LoadString(content)
return; return
} }
// ***************************************************************************** // *****************************************************************************
// *** Satisfy ISaver interface // *** Satisfy ISaver interface
// ***************************************************************************** // *****************************************************************************
func (this *Document) SaveFile(path string) (err os.Error) { func (this *Document) SaveFile(path string) (err os.Error) {
file, err := os.Open(path, os.O_WRONLY | os.O_CREAT, 0600); file, err := os.Open(path, os.O_WRONLY|os.O_CREAT, 0600)
if err != nil { if err != nil {
return return
} }
defer file.Close(); defer file.Close()
content, err := this.SaveString(); content, err := this.SaveString()
if err != nil { if err != nil {
return return
} }
file.Write(strings.Bytes(content)); file.Write([]byte(content))
return return
} }
@ -265,16 +269,15 @@ func (this *Document) SaveString() (s string, err os.Error) {
this.Version, this.Encoding, this.StandAlone) this.Version, this.Encoding, this.StandAlone)
} }
s += this.Root.String(); s += this.Root.String()
return; return
} }
func (this *Document) SaveStream(w *io.Writer) (err os.Error) { func (this *Document) SaveStream(w *io.Writer) (err os.Error) {
s, err := this.SaveString(); s, err := this.SaveString()
if err != nil { if err != nil {
return return
} }
w.Write(strings.Bytes(s)); w.Write([]byte(s))
return; return
} }

View File

@ -5,32 +5,40 @@ import "utf8"
import "regexp" import "regexp"
import "strconv" import "strconv"
var reg_entity = regexp.MustCompile("^&#[0-9]+;$"); var reg_entity = regexp.MustCompile("^&#[0-9]+;$")
// Converts a single numerical html entity to a regular Go utf-token. // Converts a single numerical html entity to a regular Go utf-token.
// ex: "♣" -> "♣" // ex: "♣" -> "♣"
func HtmlToUTF8(entity string) string { func HtmlToUTF8(entity string) string {
// Make sure we have a valid entity: { // Make sure we have a valid entity: {
ok := reg_entity.MatchString(entity); ok := reg_entity.MatchString(entity)
if !ok { return "" } if !ok {
return ""
}
// Convert entity to number // Convert entity to number
num, err := strconv.Atoi(entity[2:len(entity)-1]); num, err := strconv.Atoi(entity[2 : len(entity)-1])
if err != nil { return "" } if err != nil {
return ""
}
var arr [3]byte; var arr [3]byte
size := utf8.EncodeRune(num, &arr); size := utf8.EncodeRune(num, &arr)
if size == 0 { return "" } if size == 0 {
return ""
}
return string(&arr); return string(&arr)
} }
// Converts a single Go utf-token to it's an Html entity. // Converts a single Go utf-token to it's an Html entity.
// ex: "♣" -> "♣" // ex: "♣" -> "♣"
func UTF8ToHtml(token string) string { func UTF8ToHtml(token string) string {
rune, size := utf8.DecodeRuneInString(token); rune, size := utf8.DecodeRuneInString(token)
if size == 0 { return "" } if size == 0 {
return fmt.Sprintf("&#%d;", rune); return ""
}
return fmt.Sprintf("&#%d;", rune)
} }
/* /*
@ -46,261 +54,258 @@ func UTF8ToHtml(token string) string {
It will be used to map non-standard xml entities to a proper value. It will be used to map non-standard xml entities to a proper value.
If the parser encounters any unknown entities, it will throw a syntax If the parser encounters any unknown entities, it will throw a syntax
error and abort the parsing. Hence the ability to supply this map. error and abort the parsing. Hence the ability to supply this map.
*/ */
func loadNonStandardEntities(em *map[string]string) { func loadNonStandardEntities(em *map[string]string) {
(*em)["pi"] = "\u03c0"; (*em)["pi"] = "\u03c0"
(*em)["nabla"] = "\u2207"; (*em)["nabla"] = "\u2207"
(*em)["isin"] = "\u2208"; (*em)["isin"] = "\u2208"
(*em)["loz"] = "\u25ca"; (*em)["loz"] = "\u25ca"
(*em)["prop"] = "\u221d"; (*em)["prop"] = "\u221d"
(*em)["para"] = "\u00b6"; (*em)["para"] = "\u00b6"
(*em)["Aring"] = "\u00c5"; (*em)["Aring"] = "\u00c5"
(*em)["euro"] = "\u20ac"; (*em)["euro"] = "\u20ac"
(*em)["sup3"] = "\u00b3"; (*em)["sup3"] = "\u00b3"
(*em)["sup2"] = "\u00b2"; (*em)["sup2"] = "\u00b2"
(*em)["sup1"] = "\u00b9"; (*em)["sup1"] = "\u00b9"
(*em)["prod"] = "\u220f"; (*em)["prod"] = "\u220f"
(*em)["gamma"] = "\u03b3"; (*em)["gamma"] = "\u03b3"
(*em)["perp"] = "\u22a5"; (*em)["perp"] = "\u22a5"
(*em)["lfloor"] = "\u230a"; (*em)["lfloor"] = "\u230a"
(*em)["fnof"] = "\u0192"; (*em)["fnof"] = "\u0192"
(*em)["frasl"] = "\u2044"; (*em)["frasl"] = "\u2044"
(*em)["rlm"] = "\u200f"; (*em)["rlm"] = "\u200f"
(*em)["omega"] = "\u03c9"; (*em)["omega"] = "\u03c9"
(*em)["part"] = "\u2202"; (*em)["part"] = "\u2202"
(*em)["euml"] = "\u00eb"; (*em)["euml"] = "\u00eb"
(*em)["Kappa"] = "\u039a"; (*em)["Kappa"] = "\u039a"
(*em)["nbsp"] = "\u00a0"; (*em)["nbsp"] = "\u00a0"
(*em)["Eacute"] = "\u00c9"; (*em)["Eacute"] = "\u00c9"
(*em)["brvbar"] = "\u00a6"; (*em)["brvbar"] = "\u00a6"
(*em)["otimes"] = "\u2297"; (*em)["otimes"] = "\u2297"
(*em)["ndash"] = "\u2013"; (*em)["ndash"] = "\u2013"
(*em)["thinsp"] = "\u2009"; (*em)["thinsp"] = "\u2009"
(*em)["nu"] = "\u03bd"; (*em)["nu"] = "\u03bd"
(*em)["Upsilon"] = "\u03a5"; (*em)["Upsilon"] = "\u03a5"
(*em)["upsih"] = "\u03d2"; (*em)["upsih"] = "\u03d2"
(*em)["raquo"] = "\u00bb"; (*em)["raquo"] = "\u00bb"
(*em)["yacute"] = "\u00fd"; (*em)["yacute"] = "\u00fd"
(*em)["delta"] = "\u03b4"; (*em)["delta"] = "\u03b4"
(*em)["eth"] = "\u00f0"; (*em)["eth"] = "\u00f0"
(*em)["supe"] = "\u2287"; (*em)["supe"] = "\u2287"
(*em)["ne"] = "\u2260"; (*em)["ne"] = "\u2260"
(*em)["ni"] = "\u220b"; (*em)["ni"] = "\u220b"
(*em)["eta"] = "\u03b7"; (*em)["eta"] = "\u03b7"
(*em)["uArr"] = "\u21d1"; (*em)["uArr"] = "\u21d1"
(*em)["image"] = "\u2111"; (*em)["image"] = "\u2111"
(*em)["asymp"] = "\u2248"; (*em)["asymp"] = "\u2248"
(*em)["oacute"] = "\u00f3"; (*em)["oacute"] = "\u00f3"
(*em)["rarr"] = "\u2192"; (*em)["rarr"] = "\u2192"
(*em)["emsp"] = "\u2003"; (*em)["emsp"] = "\u2003"
(*em)["acirc"] = "\u00e2"; (*em)["acirc"] = "\u00e2"
(*em)["shy"] = "\u00ad"; (*em)["shy"] = "\u00ad"
(*em)["yuml"] = "\u00ff"; (*em)["yuml"] = "\u00ff"
(*em)["acute"] = "\u00b4"; (*em)["acute"] = "\u00b4"
(*em)["int"] = "\u222b"; (*em)["int"] = "\u222b"
(*em)["ccedil"] = "\u00e7"; (*em)["ccedil"] = "\u00e7"
(*em)["Acirc"] = "\u00c2"; (*em)["Acirc"] = "\u00c2"
(*em)["Ograve"] = "\u00d2"; (*em)["Ograve"] = "\u00d2"
(*em)["times"] = "\u00d7"; (*em)["times"] = "\u00d7"
(*em)["weierp"] = "\u2118"; (*em)["weierp"] = "\u2118"
(*em)["Tau"] = "\u03a4"; (*em)["Tau"] = "\u03a4"
(*em)["omicron"] = "\u03bf"; (*em)["omicron"] = "\u03bf"
(*em)["lt"] = "\u003c"; (*em)["lt"] = "\u003c"
(*em)["Mu"] = "\u039c"; (*em)["Mu"] = "\u039c"
(*em)["Ucirc"] = "\u00db"; (*em)["Ucirc"] = "\u00db"
(*em)["sub"] = "\u2282"; (*em)["sub"] = "\u2282"
(*em)["le"] = "\u2264"; (*em)["le"] = "\u2264"
(*em)["sum"] = "\u2211"; (*em)["sum"] = "\u2211"
(*em)["sup"] = "\u2283"; (*em)["sup"] = "\u2283"
(*em)["lrm"] = "\u200e"; (*em)["lrm"] = "\u200e"
(*em)["frac34"] = "\u00be"; (*em)["frac34"] = "\u00be"
(*em)["Iota"] = "\u0399"; (*em)["Iota"] = "\u0399"
(*em)["Ugrave"] = "\u00d9"; (*em)["Ugrave"] = "\u00d9"
(*em)["THORN"] = "\u00de"; (*em)["THORN"] = "\u00de"
(*em)["rsaquo"] = "\u203a"; (*em)["rsaquo"] = "\u203a"
(*em)["not"] = "\u00ac"; (*em)["not"] = "\u00ac"
(*em)["sigma"] = "\u03c3"; (*em)["sigma"] = "\u03c3"
(*em)["iuml"] = "\u00ef"; (*em)["iuml"] = "\u00ef"
(*em)["epsilon"] = "\u03b5"; (*em)["epsilon"] = "\u03b5"
(*em)["spades"] = "\u2660"; (*em)["spades"] = "\u2660"
(*em)["theta"] = "\u03b8"; (*em)["theta"] = "\u03b8"
(*em)["divide"] = "\u00f7"; (*em)["divide"] = "\u00f7"
(*em)["Atilde"] = "\u00c3"; (*em)["Atilde"] = "\u00c3"
(*em)["uacute"] = "\u00fa"; (*em)["uacute"] = "\u00fa"
(*em)["Rho"] = "\u03a1"; (*em)["Rho"] = "\u03a1"
(*em)["trade"] = "\u2122"; (*em)["trade"] = "\u2122"
(*em)["chi"] = "\u03c7"; (*em)["chi"] = "\u03c7"
(*em)["agrave"] = "\u00e0"; (*em)["agrave"] = "\u00e0"
(*em)["or"] = "\u2228"; (*em)["or"] = "\u2228"
(*em)["circ"] = "\u02c6"; (*em)["circ"] = "\u02c6"
(*em)["middot"] = "\u00b7"; (*em)["middot"] = "\u00b7"
(*em)["plusmn"] = "\u00b1"; (*em)["plusmn"] = "\u00b1"
(*em)["aring"] = "\u00e5"; (*em)["aring"] = "\u00e5"
(*em)["lsquo"] = "\u2018"; (*em)["lsquo"] = "\u2018"
(*em)["Yacute"] = "\u00dd"; (*em)["Yacute"] = "\u00dd"
(*em)["oline"] = "\u203e"; (*em)["oline"] = "\u203e"
(*em)["copy"] = "\u00a9"; (*em)["copy"] = "\u00a9"
(*em)["icirc"] = "\u00ee"; (*em)["icirc"] = "\u00ee"
(*em)["lowast"] = "\u2217"; (*em)["lowast"] = "\u2217"
(*em)["Oacute"] = "\u00d3"; (*em)["Oacute"] = "\u00d3"
(*em)["aacute"] = "\u00e1"; (*em)["aacute"] = "\u00e1"
(*em)["oplus"] = "\u2295"; (*em)["oplus"] = "\u2295"
(*em)["crarr"] = "\u21b5"; (*em)["crarr"] = "\u21b5"
(*em)["thetasym"] = "\u03d1"; (*em)["thetasym"] = "\u03d1"
(*em)["Beta"] = "\u0392"; (*em)["Beta"] = "\u0392"
(*em)["laquo"] = "\u00ab"; (*em)["laquo"] = "\u00ab"
(*em)["rang"] = "\u232a"; (*em)["rang"] = "\u232a"
(*em)["tilde"] = "\u02dc"; (*em)["tilde"] = "\u02dc"
(*em)["Uuml"] = "\u00dc"; (*em)["Uuml"] = "\u00dc"
(*em)["zwj"] = "\u200d"; (*em)["zwj"] = "\u200d"
(*em)["mu"] = "\u03bc"; (*em)["mu"] = "\u03bc"
(*em)["Ccedil"] = "\u00c7"; (*em)["Ccedil"] = "\u00c7"
(*em)["infin"] = "\u221e"; (*em)["infin"] = "\u221e"
(*em)["ouml"] = "\u00f6"; (*em)["ouml"] = "\u00f6"
(*em)["rfloor"] = "\u230b"; (*em)["rfloor"] = "\u230b"
(*em)["pound"] = "\u00a3"; (*em)["pound"] = "\u00a3"
(*em)["szlig"] = "\u00df"; (*em)["szlig"] = "\u00df"
(*em)["thorn"] = "\u00fe"; (*em)["thorn"] = "\u00fe"
(*em)["forall"] = "\u2200"; (*em)["forall"] = "\u2200"
(*em)["piv"] = "\u03d6"; (*em)["piv"] = "\u03d6"
(*em)["rdquo"] = "\u201d"; (*em)["rdquo"] = "\u201d"
(*em)["frac12"] = "\u00bd"; (*em)["frac12"] = "\u00bd"
(*em)["frac14"] = "\u00bc"; (*em)["frac14"] = "\u00bc"
(*em)["Ocirc"] = "\u00d4"; (*em)["Ocirc"] = "\u00d4"
(*em)["Ecirc"] = "\u00ca"; (*em)["Ecirc"] = "\u00ca"
(*em)["kappa"] = "\u03ba"; (*em)["kappa"] = "\u03ba"
(*em)["Euml"] = "\u00cb"; (*em)["Euml"] = "\u00cb"
(*em)["minus"] = "\u2212"; (*em)["minus"] = "\u2212"
(*em)["cong"] = "\u2245"; (*em)["cong"] = "\u2245"
(*em)["hellip"] = "\u2026"; (*em)["hellip"] = "\u2026"
(*em)["equiv"] = "\u2261"; (*em)["equiv"] = "\u2261"
(*em)["cent"] = "\u00a2"; (*em)["cent"] = "\u00a2"
(*em)["Uacute"] = "\u00da"; (*em)["Uacute"] = "\u00da"
(*em)["darr"] = "\u2193"; (*em)["darr"] = "\u2193"
(*em)["Eta"] = "\u0397"; (*em)["Eta"] = "\u0397"
(*em)["sbquo"] = "\u201a"; (*em)["sbquo"] = "\u201a"
(*em)["rArr"] = "\u21d2"; (*em)["rArr"] = "\u21d2"
(*em)["igrave"] = "\u00ec"; (*em)["igrave"] = "\u00ec"
(*em)["uml"] = "\u00a8"; (*em)["uml"] = "\u00a8"
(*em)["lambda"] = "\u03bb"; (*em)["lambda"] = "\u03bb"
(*em)["oelig"] = "\u0153"; (*em)["oelig"] = "\u0153"
(*em)["harr"] = "\u2194"; (*em)["harr"] = "\u2194"
(*em)["ang"] = "\u2220"; (*em)["ang"] = "\u2220"
(*em)["clubs"] = "\u2663"; (*em)["clubs"] = "\u2663"
(*em)["and"] = "\u2227"; (*em)["and"] = "\u2227"
(*em)["permil"] = "\u2030"; (*em)["permil"] = "\u2030"
(*em)["larr"] = "\u2190"; (*em)["larr"] = "\u2190"
(*em)["Yuml"] = "\u0178"; (*em)["Yuml"] = "\u0178"
(*em)["cup"] = "\u222a"; (*em)["cup"] = "\u222a"
(*em)["Xi"] = "\u039e"; (*em)["Xi"] = "\u039e"
(*em)["Alpha"] = "\u0391"; (*em)["Alpha"] = "\u0391"
(*em)["phi"] = "\u03c6"; (*em)["phi"] = "\u03c6"
(*em)["ucirc"] = "\u00fb"; (*em)["ucirc"] = "\u00fb"
(*em)["oslash"] = "\u00f8"; (*em)["oslash"] = "\u00f8"
(*em)["rsquo"] = "\u2019"; (*em)["rsquo"] = "\u2019"
(*em)["AElig"] = "\u00c6"; (*em)["AElig"] = "\u00c6"
(*em)["mdash"] = "\u2014"; (*em)["mdash"] = "\u2014"
(*em)["psi"] = "\u03c8"; (*em)["psi"] = "\u03c8"
(*em)["eacute"] = "\u00e9"; (*em)["eacute"] = "\u00e9"
(*em)["otilde"] = "\u00f5"; (*em)["otilde"] = "\u00f5"
(*em)["yen"] = "\u00a5"; (*em)["yen"] = "\u00a5"
(*em)["gt"] = "\u003e"; (*em)["gt"] = "\u003e"
(*em)["Iuml"] = "\u00cf"; (*em)["Iuml"] = "\u00cf"
(*em)["Prime"] = "\u2033"; (*em)["Prime"] = "\u2033"
(*em)["Chi"] = "\u03a7"; (*em)["Chi"] = "\u03a7"
(*em)["ge"] = "\u2265"; (*em)["ge"] = "\u2265"
(*em)["reg"] = "\u00ae"; (*em)["reg"] = "\u00ae"
(*em)["hearts"] = "\u2665"; (*em)["hearts"] = "\u2665"
(*em)["auml"] = "\u00e4"; (*em)["auml"] = "\u00e4"
(*em)["Agrave"] = "\u00c0"; (*em)["Agrave"] = "\u00c0"
(*em)["sect"] = "\u00a7"; (*em)["sect"] = "\u00a7"
(*em)["sube"] = "\u2286"; (*em)["sube"] = "\u2286"
(*em)["sigmaf"] = "\u03c2"; (*em)["sigmaf"] = "\u03c2"
(*em)["Gamma"] = "\u0393"; (*em)["Gamma"] = "\u0393"
(*em)["amp"] = "\u0026"; (*em)["amp"] = "\u0026"
(*em)["ensp"] = "\u2002"; (*em)["ensp"] = "\u2002"
(*em)["ETH"] = "\u00d0"; (*em)["ETH"] = "\u00d0"
(*em)["Igrave"] = "\u00cc"; (*em)["Igrave"] = "\u00cc"
(*em)["Omega"] = "\u03a9"; (*em)["Omega"] = "\u03a9"
(*em)["Lambda"] = "\u039b"; (*em)["Lambda"] = "\u039b"
(*em)["Omicron"] = "\u039f"; (*em)["Omicron"] = "\u039f"
(*em)["there4"] = "\u2234"; (*em)["there4"] = "\u2234"
(*em)["ntilde"] = "\u00f1"; (*em)["ntilde"] = "\u00f1"
(*em)["xi"] = "\u03be"; (*em)["xi"] = "\u03be"
(*em)["dagger"] = "\u2020"; (*em)["dagger"] = "\u2020"
(*em)["egrave"] = "\u00e8"; (*em)["egrave"] = "\u00e8"
(*em)["Delta"] = "\u0394"; (*em)["Delta"] = "\u0394"
(*em)["OElig"] = "\u0152"; (*em)["OElig"] = "\u0152"
(*em)["diams"] = "\u2666"; (*em)["diams"] = "\u2666"
(*em)["ldquo"] = "\u201c"; (*em)["ldquo"] = "\u201c"
(*em)["radic"] = "\u221a"; (*em)["radic"] = "\u221a"
(*em)["Oslash"] = "\u00d8"; (*em)["Oslash"] = "\u00d8"
(*em)["Ouml"] = "\u00d6"; (*em)["Ouml"] = "\u00d6"
(*em)["lceil"] = "\u2308"; (*em)["lceil"] = "\u2308"
(*em)["uarr"] = "\u2191"; (*em)["uarr"] = "\u2191"
(*em)["atilde"] = "\u00e3"; (*em)["atilde"] = "\u00e3"
(*em)["iquest"] = "\u00bf"; (*em)["iquest"] = "\u00bf"
(*em)["lsaquo"] = "\u2039"; (*em)["lsaquo"] = "\u2039"
(*em)["Epsilon"] = "\u0395"; (*em)["Epsilon"] = "\u0395"
(*em)["iacute"] = "\u00ed"; (*em)["iacute"] = "\u00ed"
(*em)["cap"] = "\u2229"; (*em)["cap"] = "\u2229"
(*em)["deg"] = "\u00b0"; (*em)["deg"] = "\u00b0"
(*em)["Otilde"] = "\u00d5"; (*em)["Otilde"] = "\u00d5"
(*em)["zeta"] = "\u03b6"; (*em)["zeta"] = "\u03b6"
(*em)["ocirc"] = "\u00f4"; (*em)["ocirc"] = "\u00f4"
(*em)["scaron"] = "\u0161"; (*em)["scaron"] = "\u0161"
(*em)["ecirc"] = "\u00ea"; (*em)["ecirc"] = "\u00ea"
(*em)["ordm"] = "\u00ba"; (*em)["ordm"] = "\u00ba"
(*em)["tau"] = "\u03c4"; (*em)["tau"] = "\u03c4"
(*em)["Auml"] = "\u00c4"; (*em)["Auml"] = "\u00c4"
(*em)["dArr"] = "\u21d3"; (*em)["dArr"] = "\u21d3"
(*em)["ordf"] = "\u00aa"; (*em)["ordf"] = "\u00aa"
(*em)["alefsym"] = "\u2135"; (*em)["alefsym"] = "\u2135"
(*em)["notin"] = "\u2209"; (*em)["notin"] = "\u2209"
(*em)["Pi"] = "\u03a0"; (*em)["Pi"] = "\u03a0"
(*em)["sdot"] = "\u22c5"; (*em)["sdot"] = "\u22c5"
(*em)["upsilon"] = "\u03c5"; (*em)["upsilon"] = "\u03c5"
(*em)["iota"] = "\u03b9"; (*em)["iota"] = "\u03b9"
(*em)["hArr"] = "\u21d4"; (*em)["hArr"] = "\u21d4"
(*em)["Sigma"] = "\u03a3"; (*em)["Sigma"] = "\u03a3"
(*em)["lang"] = "\u2329"; (*em)["lang"] = "\u2329"
(*em)["curren"] = "\u00a4"; (*em)["curren"] = "\u00a4"
(*em)["Theta"] = "\u0398"; (*em)["Theta"] = "\u0398"
(*em)["lArr"] = "\u21d0"; (*em)["lArr"] = "\u21d0"
(*em)["Phi"] = "\u03a6"; (*em)["Phi"] = "\u03a6"
(*em)["Nu"] = "\u039d"; (*em)["Nu"] = "\u039d"
(*em)["rho"] = "\u03c1"; (*em)["rho"] = "\u03c1"
(*em)["alpha"] = "\u03b1"; (*em)["alpha"] = "\u03b1"
(*em)["iexcl"] = "\u00a1"; (*em)["iexcl"] = "\u00a1"
(*em)["micro"] = "\u00b5"; (*em)["micro"] = "\u00b5"
(*em)["cedil"] = "\u00b8"; (*em)["cedil"] = "\u00b8"
(*em)["Ntilde"] = "\u00d1"; (*em)["Ntilde"] = "\u00d1"
(*em)["Psi"] = "\u03a8"; (*em)["Psi"] = "\u03a8"
(*em)["Dagger"] = "\u2021"; (*em)["Dagger"] = "\u2021"
(*em)["Egrave"] = "\u00c8"; (*em)["Egrave"] = "\u00c8"
(*em)["Icirc"] = "\u00ce"; (*em)["Icirc"] = "\u00ce"
(*em)["nsub"] = "\u2284"; (*em)["nsub"] = "\u2284"
(*em)["bdquo"] = "\u201e"; (*em)["bdquo"] = "\u201e"
(*em)["empty"] = "\u2205"; (*em)["empty"] = "\u2205"
(*em)["aelig"] = "\u00e6"; (*em)["aelig"] = "\u00e6"
(*em)["ograve"] = "\u00f2"; (*em)["ograve"] = "\u00f2"
(*em)["macr"] = "\u00af"; (*em)["macr"] = "\u00af"
(*em)["Zeta"] = "\u0396"; (*em)["Zeta"] = "\u0396"
(*em)["beta"] = "\u03b2"; (*em)["beta"] = "\u03b2"
(*em)["sim"] = "\u223c"; (*em)["sim"] = "\u223c"
(*em)["uuml"] = "\u00fc"; (*em)["uuml"] = "\u00fc"
(*em)["Aacute"] = "\u00c1"; (*em)["Aacute"] = "\u00c1"
(*em)["Iacute"] = "\u00cd"; (*em)["Iacute"] = "\u00cd"
(*em)["exist"] = "\u2203"; (*em)["exist"] = "\u2203"
(*em)["prime"] = "\u2032"; (*em)["prime"] = "\u2032"
(*em)["rceil"] = "\u2309"; (*em)["rceil"] = "\u2309"
(*em)["real"] = "\u211c"; (*em)["real"] = "\u211c"
(*em)["zwnj"] = "\u200c"; (*em)["zwnj"] = "\u200c"
(*em)["bull"] = "\u2022"; (*em)["bull"] = "\u2022"
(*em)["quot"] = "\u0022"; (*em)["quot"] = "\u0022"
(*em)["Scaron"] = "\u0160"; (*em)["Scaron"] = "\u0160"
(*em)["ugrave"] = "\u00f9"; (*em)["ugrave"] = "\u00f9"
} }

View File

@ -4,19 +4,19 @@ import "os"
import "io" import "io"
type ILoader interface { type ILoader interface {
LoadUrl(string) os.Error; LoadUrl(string) os.Error
LoadFile(string) os.Error; LoadFile(string) os.Error
LoadString(string) os.Error; LoadString(string) os.Error
LoadStream(*io.Reader) os.Error; LoadStream(*io.Reader) os.Error
} }
type ISaver interface { type ISaver interface {
SaveFile(string) os.Error; SaveFile(string) os.Error
SaveString(string) (string, os.Error); SaveString(string) (string, os.Error)
SaveStream(*io.Writer) os.Error; SaveStream(*io.Writer) os.Error
} }
type ILoaderSaver interface { type ILoaderSaver interface {
ILoader; ILoader
ISaver; ISaver
} }

View File

@ -7,26 +7,26 @@ import "fmt"
import "strconv" import "strconv"
const ( const (
NT_ROOT = 0x00; NT_ROOT = 0x00
NT_DIRECTIVE = 0x01; NT_DIRECTIVE = 0x01
NT_PROCINST = 0x02; NT_PROCINST = 0x02
NT_COMMENT = 0x03; NT_COMMENT = 0x03
NT_ELEMENT = 0x04; NT_ELEMENT = 0x04
) )
type Attr struct { type Attr struct {
Name xml.Name; Name xml.Name
Value string; Value string
} }
type Node struct { type Node struct {
Type byte; Type byte
Name xml.Name; Name xml.Name
Children []*Node; Children []*Node
Attributes []Attr; Attributes []Attr
Parent *Node; Parent *Node
Value string; Value string
Target string; // procinst field Target string // procinst field
} }
func NewNode(tid byte) *Node { return &Node{Type: tid} } func NewNode(tid byte) *Node { return &Node{Type: tid} }
@ -34,148 +34,192 @@ func NewNode(tid byte) *Node { return &Node{Type: tid} }
// This wraps the standard xml.Unmarshal function and supplies this particular // This wraps the standard xml.Unmarshal function and supplies this particular
// node as the content to be unmarshalled. // node as the content to be unmarshalled.
func (this *Node) Unmarshal(obj interface{}) os.Error { func (this *Node) Unmarshal(obj interface{}) os.Error {
return xml.Unmarshal(strings.NewReader(this.String()), obj); return xml.Unmarshal(strings.NewReader(this.String()), obj)
} }
// Get node value as string // Get node value as string
func (this *Node) GetValue(namespace, name string) string { func (this *Node) GetValue(namespace, name string) string {
node := rec_SelectNode(this, namespace, name); node := rec_SelectNode(this, namespace, name)
if node == nil { return "" } if node == nil {
return node.Value; return ""
}
return node.Value
} }
// Get node value as int // Get node value as int
func (this *Node) GetValuei(namespace, name string) int { func (this *Node) GetValuei(namespace, name string) int {
node := rec_SelectNode(this, namespace, name); node := rec_SelectNode(this, namespace, name)
if node == nil { return 0 } if node == nil {
if node.Value == "" { return 0 } return 0
n, _ := strconv.Atoi(node.Value); }
return n; if node.Value == "" {
return 0
}
n, _ := strconv.Atoi(node.Value)
return n
} }
// Get node value as int64 // Get node value as int64
func (this *Node) GetValuei64(namespace, name string) int64 { func (this *Node) GetValuei64(namespace, name string) int64 {
node := rec_SelectNode(this, namespace, name); node := rec_SelectNode(this, namespace, name)
if node == nil { return 0 } if node == nil {
if node.Value == "" { return 0 } return 0
n, _ := strconv.Atoi64(node.Value); }
return n; if node.Value == "" {
return 0
}
n, _ := strconv.Atoi64(node.Value)
return n
} }
// Get node value as uint // Get node value as uint
func (this *Node) GetValueui(namespace, name string) uint { func (this *Node) GetValueui(namespace, name string) uint {
node := rec_SelectNode(this, namespace, name); node := rec_SelectNode(this, namespace, name)
if node == nil { return 0 } if node == nil {
if node.Value == "" { return 0 } return 0
n, _ := strconv.Atoui(node.Value); }
return n; if node.Value == "" {
return 0
}
n, _ := strconv.Atoui(node.Value)
return n
} }
// Get node value as uint64 // Get node value as uint64
func (this *Node) GetValueui64(namespace, name string) uint64 { func (this *Node) GetValueui64(namespace, name string) uint64 {
node := rec_SelectNode(this, namespace, name); node := rec_SelectNode(this, namespace, name)
if node == nil { return 0 } if node == nil {
if node.Value == "" { return 0 } return 0
n, _ := strconv.Atoui64(node.Value); }
return n; if node.Value == "" {
return 0
}
n, _ := strconv.Atoui64(node.Value)
return n
} }
// Get node value as float // Get node value as float
func (this *Node) GetValuef(namespace, name string) float { func (this *Node) GetValuef(namespace, name string) float {
node := rec_SelectNode(this, namespace, name); node := rec_SelectNode(this, namespace, name)
if node == nil { return 0 } if node == nil {
if node.Value == "" { return 0 } return 0
n, _ := strconv.Atof(node.Value); }
return n; if node.Value == "" {
return 0
}
n, _ := strconv.Atof(node.Value)
return n
} }
// Get node value as float32 // Get node value as float32
func (this *Node) GetValuef32(namespace, name string) float32 { func (this *Node) GetValuef32(namespace, name string) float32 {
node := rec_SelectNode(this, namespace, name); node := rec_SelectNode(this, namespace, name)
if node == nil { return 0 } if node == nil {
if node.Value == "" { return 0 } return 0
n, _ := strconv.Atof32(node.Value); }
return n; if node.Value == "" {
return 0
}
n, _ := strconv.Atof32(node.Value)
return n
} }
// Get node value as float64 // Get node value as float64
func (this *Node) GetValuef64(namespace, name string) float64 { func (this *Node) GetValuef64(namespace, name string) float64 {
node := rec_SelectNode(this, namespace, name); node := rec_SelectNode(this, namespace, name)
if node == nil { return 0 } if node == nil {
if node.Value == "" { return 0 } return 0
n, _ := strconv.Atof64(node.Value); }
return n; if node.Value == "" {
return 0
}
n, _ := strconv.Atof64(node.Value)
return n
} }
// Get attribute value as string // Get attribute value as string
func (this *Node) GetAttr(namespace, name string) string { func (this *Node) GetAttr(namespace, name string) string {
for _,v := range this.Attributes { for _, v := range this.Attributes {
if namespace == v.Name.Space && name == v.Name.Local { if namespace == v.Name.Space && name == v.Name.Local {
return v.Value; return v.Value
} }
} }
return ""; return ""
} }
// Get attribute value as int // Get attribute value as int
func (this *Node) GetAttri(namespace, name string) int { func (this *Node) GetAttri(namespace, name string) int {
s := this.GetAttr(namespace, name); s := this.GetAttr(namespace, name)
if s == "" { return 0 } if s == "" {
n, _ := strconv.Atoi(s); return 0
return n; }
n, _ := strconv.Atoi(s)
return n
} }
// Get attribute value as uint // Get attribute value as uint
func (this *Node) GetAttrui(namespace, name string) uint { func (this *Node) GetAttrui(namespace, name string) uint {
s := this.GetAttr(namespace, name); s := this.GetAttr(namespace, name)
if s == "" { return 0 } if s == "" {
n, _ := strconv.Atoui(s); return 0
return n; }
n, _ := strconv.Atoui(s)
return n
} }
// Get attribute value as uint64 // Get attribute value as uint64
func (this *Node) GetAttrui64(namespace, name string) uint64 { func (this *Node) GetAttrui64(namespace, name string) uint64 {
s := this.GetAttr(namespace, name); s := this.GetAttr(namespace, name)
if s == "" { return 0 } if s == "" {
n, _ := strconv.Atoui64(s); return 0
return n; }
n, _ := strconv.Atoui64(s)
return n
} }
// Get attribute value as int64 // Get attribute value as int64
func (this *Node) GetAttri64(namespace, name string) int64 { func (this *Node) GetAttri64(namespace, name string) int64 {
s := this.GetAttr(namespace, name); s := this.GetAttr(namespace, name)
if s == "" { return 0 } if s == "" {
n, _ := strconv.Atoi64(s); return 0
return n; }
n, _ := strconv.Atoi64(s)
return n
} }
// Get attribute value as float // Get attribute value as float
func (this *Node) GetAttrf(namespace, name string) float { func (this *Node) GetAttrf(namespace, name string) float {
s := this.GetAttr(namespace, name); s := this.GetAttr(namespace, name)
if s == "" { return 0 } if s == "" {
n, _ := strconv.Atof(s); return 0
return n; }
n, _ := strconv.Atof(s)
return n
} }
// Get attribute value as float32 // Get attribute value as float32
func (this *Node) GetAttrf32(namespace, name string) float32 { func (this *Node) GetAttrf32(namespace, name string) float32 {
s := this.GetAttr(namespace, name); s := this.GetAttr(namespace, name)
if s == "" { return 0 } if s == "" {
n, _ := strconv.Atof32(s); return 0
return n; }
n, _ := strconv.Atof32(s)
return n
} }
// Get attribute value as float64 // Get attribute value as float64
func (this *Node) GetAttrf64(namespace, name string) float64 { func (this *Node) GetAttrf64(namespace, name string) float64 {
s := this.GetAttr(namespace, name); s := this.GetAttr(namespace, name)
if s == "" { return 0 } if s == "" {
n, _ := strconv.Atof64(s); return 0
return n; }
n, _ := strconv.Atof64(s)
return n
} }
// 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 == v.Name.Space && name == v.Name.Local { if namespace == v.Name.Space && name == v.Name.Local {
return true return true
} }
@ -185,41 +229,41 @@ func (this *Node) HasAttr(namespace, name string) bool {
// Select single node by name // Select single node by name
func (this *Node) SelectNode(namespace, name string) *Node { func (this *Node) SelectNode(namespace, name string) *Node {
return rec_SelectNode(this, namespace, name); return rec_SelectNode(this, namespace, name)
} }
func rec_SelectNode(cn *Node, namespace, name string) *Node { func rec_SelectNode(cn *Node, namespace, name string) *Node {
if cn.Name.Space == namespace && cn.Name.Local == name { if cn.Name.Space == namespace && cn.Name.Local == name {
return cn; return cn
} }
for _, v := range cn.Children { for _, v := range cn.Children {
tn := rec_SelectNode(v, namespace, name); tn := rec_SelectNode(v, namespace, name)
if tn != nil { return tn } if tn != nil {
return tn
} }
return nil; }
return nil
} }
// 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); list := make([]*Node, 0)
rec_SelectNodes(this, namespace, name, &list); rec_SelectNodes(this, namespace, name, &list)
return list; return list
} }
func rec_SelectNodes(cn *Node, namespace, name string, list *[]*Node) { func rec_SelectNodes(cn *Node, namespace, name string, list *[]*Node) {
if cn.Name.Space == namespace && cn.Name.Local == name { if cn.Name.Space == namespace && cn.Name.Local == name {
slice := make([]*Node, len(*list) + 1); c := make([]*Node, len(*list)+1)
for i,v := range *list { copy(c, *list)
slice[i] = v; c[len(c)-1] = cn
} *list = c
slice[len(slice) - 1] = cn;
*list = slice;
return return
} }
for _, v := range cn.Children { for _, v := range cn.Children {
rec_SelectNodes(v, namespace, name, list); rec_SelectNodes(v, namespace, name, list)
} }
} }
@ -240,29 +284,29 @@ func (this *Node) String() (s string) {
case NT_ROOT: case NT_ROOT:
s = this.printRoot() s = this.printRoot()
} }
return; return
} }
func (this *Node) printRoot() (s string) { func (this *Node) printRoot() (s string) {
for _, v := range this.Children { for _, v := range this.Children {
s += v.String() s += v.String()
} }
return; return
} }
func (this *Node) printProcInst() (s string) { func (this *Node) printProcInst() (s string) {
s = "<?" + this.Target + " " + this.Value + "?>"; s = "<?" + this.Target + " " + this.Value + "?>"
return; return
} }
func (this *Node) printComment() (s string) { func (this *Node) printComment() (s string) {
s = "<!-- " + this.Value + " -->"; s = "<!-- " + this.Value + " -->"
return; return
} }
func (this *Node) printDirective() (s string) { func (this *Node) printDirective() (s string) {
s = "<!" + this.Value + "!>"; s = "<!" + this.Value + "!>"
return; return
} }
func (this *Node) printElement() (s string) { func (this *Node) printElement() (s string) {
@ -281,23 +325,23 @@ func (this *Node) printElement() (s string) {
} }
if len(this.Children) == 0 && len(this.Value) == 0 { if len(this.Children) == 0 && len(this.Value) == 0 {
s += " />"; s += " />"
return; return
} }
s += ">"; s += ">"
for _, v := range this.Children { for _, v := range this.Children {
s += v.String() s += v.String()
} }
s += this.Value; s += this.Value
if len(this.Name.Space) > 0 { if len(this.Name.Space) > 0 {
s += "</" + this.Name.Space + ":" + this.Name.Local + ">" s += "</" + this.Name.Space + ":" + this.Name.Local + ">"
} else { } else {
s += "</" + this.Name.Local + ">" s += "</" + this.Name.Local + ">"
} }
return; return
} }
// Add a child node // Add a child node
@ -305,38 +349,32 @@ func (this *Node) AddChild(t *Node) {
if t.Parent != nil { if t.Parent != nil {
t.Parent.RemoveChild(t) t.Parent.RemoveChild(t)
} }
t.Parent = this; t.Parent = this
slice := make([]*Node, len(this.Children)+1); c := make([]*Node, len(this.Children)+1)
for i, v := range this.Children { copy(c, this.Children)
slice[i] = v c[len(c)-1] = t
} this.Children = c
slice[len(slice)-1] = t;
this.Children = slice;
} }
// Remove a child node // Remove a child node
func (this *Node) RemoveChild(t *Node) { func (this *Node) RemoveChild(t *Node) {
pos := -1; p := -1
for i, v := range this.Children { for i, v := range this.Children {
if v == t { if v == t {
pos = i; p = i
break; break
} }
} }
if pos == -1 { if p == -1 {
return return
} }
slice := make([]*Node, len(this.Children)-1);
idx := 0; c := make([]*Node, len(this.Children)-1)
for i, v := range this.Children { copy(c, this.Children[0:p])
if i != pos { copy(c[p:], this.Children[p+1:])
slice[idx] = v; this.Children = c
idx++;
}
}
t.Parent = nil; t.Parent = nil
} }

View File

@ -3,108 +3,106 @@ package xmlx
import "testing" import "testing"
func TestLoadLocal(t *testing.T) { func TestLoadLocal(t *testing.T) {
doc := New(); doc := New()
err := doc.LoadFile("test.xml"); err := doc.LoadFile("test.xml")
if err != nil { if err != nil {
t.Errorf("%s", err); t.Errorf("%s", err)
return; return
} }
if len(doc.Root.Children) == 0 { if len(doc.Root.Children) == 0 {
t.Errorf("Root node has no children."); t.Errorf("Root node has no children.")
return; return
} }
} }
func TestLoadRemote(t *testing.T) { func TestLoadRemote(t *testing.T) {
doc := New(); doc := New()
err := doc.LoadUri("http://tldp.org/authors/template/Sample-HOWTO.xml"); err := doc.LoadUri("http://tldp.org/authors/template/Sample-HOWTO.xml")
if err != nil { if err != nil {
t.Errorf("%s", err); t.Errorf("%s", err)
return; return
} }
if len(doc.Root.Children) == 0 { if len(doc.Root.Children) == 0 {
t.Errorf("Root node has no children."); t.Errorf("Root node has no children.")
return; return
} }
} }
func TestSave(t *testing.T) { func TestSave(t *testing.T) {
doc := New(); doc := New()
err := doc.LoadFile("test.xml"); err := doc.LoadFile("test.xml")
if err != nil { if err != nil {
t.Errorf("LoadFile(): %s", err); t.Errorf("LoadFile(): %s", err)
return; return
} }
err = doc.SaveFile("test1.xml"); err = doc.SaveFile("test1.xml")
if err != nil { if err != nil {
t.Errorf("SaveFile(): %s", err); t.Errorf("SaveFile(): %s", err)
return; return
} }
} }
func TestNodeSearch(t *testing.T) { func TestNodeSearch(t *testing.T) {
doc := New(); doc := New()
err := doc.LoadFile("test.xml"); err := doc.LoadFile("test.xml")
if err != nil { if err != nil {
t.Errorf("LoadFile(): %s", err); t.Errorf("LoadFile(): %s", err)
return; return
} }
node := doc.SelectNode("", "item"); node := doc.SelectNode("", "item")
if node == nil { if node == nil {
t.Errorf("SelectNode(): No node found."); t.Errorf("SelectNode(): No node found.")
return; return
} }
nodes := doc.SelectNodes("", "item"); nodes := doc.SelectNodes("", "item")
if len(nodes) == 0 { if len(nodes) == 0 {
t.Errorf("SelectNodes(): no nodes found."); t.Errorf("SelectNodes(): no nodes found.")
return; return
} }
} }
type Image struct { type Image struct {
Title string; Title string
Url string; Url string
Link string; Link string
Width string; Width string
Height string; Height string
Description string; Description string
} }
func TestUnmarshal(t *testing.T) { func TestUnmarshal(t *testing.T) {
doc := New(); doc := New()
err := doc.LoadFile("test.xml"); err := doc.LoadFile("test.xml")
if err != nil { if err != nil {
t.Errorf("LoadFile(): %s", err); t.Errorf("LoadFile(): %s", err)
return; return
} }
node := doc.SelectNode("", "image"); node := doc.SelectNode("", "image")
if node == nil { if node == nil {
t.Errorf("SelectNode(): No node found."); t.Errorf("SelectNode(): No node found.")
return; return
} }
img := Image{}; img := Image{}
err = node.Unmarshal(&img); err = node.Unmarshal(&img)
if err != nil { if err != nil {
t.Errorf("Unmarshal(): %s", err); t.Errorf("Unmarshal(): %s", err)
return; return
} }
if img.Title != "WriteTheWeb" { if img.Title != "WriteTheWeb" {
t.Errorf("Image.Title has incorrect value. Got '%s', expected 'WriteTheWeb'.", img.Title); t.Errorf("Image.Title has incorrect value. Got '%s', expected 'WriteTheWeb'.", img.Title)
return; return
} }
} }