fixed some slice copy routines
This commit is contained in:
		
							parent
							
								
									379dfddd5b
								
							
						
					
					
						commit
						6a776b0cda
					
				
					 5 changed files with 602 additions and 558 deletions
				
			
		
							
								
								
									
										173
									
								
								src/document.go
									
										
									
									
									
								
							
							
						
						
									
										173
									
								
								src/document.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -35,13 +35,13 @@ import "fmt"
 | 
			
		|||
import "http"
 | 
			
		||||
 | 
			
		||||
type Document struct {
 | 
			
		||||
	Version		string;
 | 
			
		||||
	Encoding	string;
 | 
			
		||||
	StandAlone	string;
 | 
			
		||||
	SaveDocType	bool;
 | 
			
		||||
	Root		*Node;
 | 
			
		||||
	Entity		map[string]string;
 | 
			
		||||
	Verbose		bool;
 | 
			
		||||
	Version     string
 | 
			
		||||
	Encoding    string
 | 
			
		||||
	StandAlone  string
 | 
			
		||||
	SaveDocType bool
 | 
			
		||||
	Root        *Node
 | 
			
		||||
	Entity      map[string]string
 | 
			
		||||
	Verbose     bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func New() *Document {
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +51,7 @@ func New() *Document {
 | 
			
		|||
		StandAlone:  "yes",
 | 
			
		||||
		SaveDocType: true,
 | 
			
		||||
		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
 | 
			
		||||
// 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
 | 
			
		||||
func (this *Document) LoadExtendedEntityMap() {
 | 
			
		||||
	loadNonStandardEntities(&this.Entity);
 | 
			
		||||
}
 | 
			
		||||
func (this *Document) LoadExtendedEntityMap() { loadNonStandardEntities(&this.Entity) }
 | 
			
		||||
 | 
			
		||||
func (this *Document) String() string {
 | 
			
		||||
	s, _ := this.SaveString();
 | 
			
		||||
	return s;
 | 
			
		||||
	s, _ := this.SaveString()
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
	return this.Root.SelectNodes(namespace, name);
 | 
			
		||||
	return this.Root.SelectNodes(namespace, name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// *****************************************************************************
 | 
			
		||||
// *** Satisfy ILoader interface
 | 
			
		||||
// *****************************************************************************
 | 
			
		||||
func (this *Document) LoadString(s string) (err os.Error) {
 | 
			
		||||
	xp := xml.NewParser(strings.NewReader(s));
 | 
			
		||||
	xp.Entity = this.Entity;
 | 
			
		||||
	xp := xml.NewParser(strings.NewReader(s))
 | 
			
		||||
	xp.Entity = this.Entity
 | 
			
		||||
 | 
			
		||||
	this.Root = NewNode(NT_ROOT);
 | 
			
		||||
	ct := this.Root;
 | 
			
		||||
	this.Root = NewNode(NT_ROOT)
 | 
			
		||||
	ct := this.Root
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		tok, err := xp.Token();
 | 
			
		||||
		tok, err := xp.Token()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			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
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		t1, ok := tok.(xml.SyntaxError);
 | 
			
		||||
		t1, ok := tok.(xml.SyntaxError)
 | 
			
		||||
		if ok {
 | 
			
		||||
			err = os.NewError(t1.String());
 | 
			
		||||
			err = os.NewError(t1.String())
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		t2, ok := tok.(xml.CharData);
 | 
			
		||||
		t2, ok := tok.(xml.CharData)
 | 
			
		||||
		if ok && ct != nil {
 | 
			
		||||
			ct.Value = strings.TrimSpace(string(t2));
 | 
			
		||||
			ct.Value = strings.TrimSpace(string(t2))
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		t3, ok := tok.(xml.Comment);
 | 
			
		||||
		t3, ok := tok.(xml.Comment)
 | 
			
		||||
		if ok && ct != nil {
 | 
			
		||||
			t := NewNode(NT_COMMENT);
 | 
			
		||||
			t.Value = strings.TrimSpace(string(t3));
 | 
			
		||||
			ct.AddChild(t);
 | 
			
		||||
			t := NewNode(NT_COMMENT)
 | 
			
		||||
			t.Value = strings.TrimSpace(string(t3))
 | 
			
		||||
			ct.AddChild(t)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		t4, ok := tok.(xml.Directive);
 | 
			
		||||
		t4, ok := tok.(xml.Directive)
 | 
			
		||||
		if ok && ct != nil {
 | 
			
		||||
			t := NewNode(NT_DIRECTIVE);
 | 
			
		||||
			t.Value = strings.TrimSpace(string(t4));
 | 
			
		||||
			ct.AddChild(t);
 | 
			
		||||
			t := NewNode(NT_DIRECTIVE)
 | 
			
		||||
			t.Value = strings.TrimSpace(string(t4))
 | 
			
		||||
			ct.AddChild(t)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		t5, ok := tok.(xml.StartElement);
 | 
			
		||||
		t5, ok := tok.(xml.StartElement)
 | 
			
		||||
		if ok && ct != nil {
 | 
			
		||||
			t := NewNode(NT_ELEMENT);
 | 
			
		||||
			t.Name = t5.Name;
 | 
			
		||||
			t.Attributes = make([]Attr, len(t5.Attr));
 | 
			
		||||
			t := NewNode(NT_ELEMENT)
 | 
			
		||||
			t.Name = t5.Name
 | 
			
		||||
			t.Attributes = make([]Attr, len(t5.Attr))
 | 
			
		||||
			for i, v := range t5.Attr {
 | 
			
		||||
				t.Attributes[i].Name = v.Name;
 | 
			
		||||
				t.Attributes[i].Value = v.Value;
 | 
			
		||||
				t.Attributes[i].Name = v.Name
 | 
			
		||||
				t.Attributes[i].Value = v.Value
 | 
			
		||||
			}
 | 
			
		||||
			ct.AddChild(t);
 | 
			
		||||
			ct = t;
 | 
			
		||||
			ct.AddChild(t)
 | 
			
		||||
			ct = t
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		t6, ok := tok.(xml.ProcInst);
 | 
			
		||||
		t6, ok := tok.(xml.ProcInst)
 | 
			
		||||
		if ok {
 | 
			
		||||
			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
 | 
			
		||||
				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 {
 | 
			
		||||
					this.StandAlone = doctype[pos+len(`standalone="`) : len(doctype)];
 | 
			
		||||
					pos = strings.Index(this.StandAlone, `"`);
 | 
			
		||||
					this.StandAlone = this.StandAlone[0:pos];
 | 
			
		||||
					this.StandAlone = doctype[pos+len(`standalone="`) : len(doctype)]
 | 
			
		||||
					pos = strings.Index(this.StandAlone, `"`)
 | 
			
		||||
					this.StandAlone = this.StandAlone[0:pos]
 | 
			
		||||
				}
 | 
			
		||||
			} else if ct != nil {
 | 
			
		||||
				t := NewNode(NT_PROCINST);
 | 
			
		||||
				t.Target = strings.TrimSpace(t6.Target);
 | 
			
		||||
				t.Value = strings.TrimSpace(string(t6.Inst));
 | 
			
		||||
				ct.AddChild(t);
 | 
			
		||||
				t := NewNode(NT_PROCINST)
 | 
			
		||||
				t.Target = strings.TrimSpace(t6.Target)
 | 
			
		||||
				t.Value = strings.TrimSpace(string(t6.Inst))
 | 
			
		||||
				ct.AddChild(t)
 | 
			
		||||
			}
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		_, ok = tok.(xml.EndElement);
 | 
			
		||||
		_, ok = tok.(xml.EndElement)
 | 
			
		||||
		if ok {
 | 
			
		||||
			ct = ct.Parent;
 | 
			
		||||
			ct = ct.Parent
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	defer file.Close();
 | 
			
		||||
	defer file.Close()
 | 
			
		||||
 | 
			
		||||
	content := "";
 | 
			
		||||
	buff := make([]byte, 256);
 | 
			
		||||
	content := ""
 | 
			
		||||
	buff := make([]byte, 256)
 | 
			
		||||
	for {
 | 
			
		||||
		_, err := file.Read(buff);
 | 
			
		||||
		_, err := file.Read(buff)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		content += string(buff);
 | 
			
		||||
		content += string(buff)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = this.LoadString(content);
 | 
			
		||||
	return;
 | 
			
		||||
	err = this.LoadString(content)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Document) LoadUri(uri string) (err os.Error) {
 | 
			
		||||
	r, _, err := http.Get(uri);
 | 
			
		||||
	r, _, err := http.Get(uri)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer r.Body.Close();
 | 
			
		||||
	defer r.Body.Close()
 | 
			
		||||
 | 
			
		||||
	b, err := io.ReadAll(r.Body);
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	data := ""
 | 
			
		||||
	b := make([]byte, 256)
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		n, err := io.ReadFull(r.Body, b)
 | 
			
		||||
		if n == 0 || err == os.EOF {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		data += string(b)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = this.LoadString(string(b));
 | 
			
		||||
	return;
 | 
			
		||||
	err = this.LoadString(data)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Document) LoadStream(r *io.Reader) (err os.Error) {
 | 
			
		||||
	content := "";
 | 
			
		||||
	buff := make([]byte, 256);
 | 
			
		||||
	content := ""
 | 
			
		||||
	buff := make([]byte, 256)
 | 
			
		||||
	for {
 | 
			
		||||
		_, err := r.Read(buff);
 | 
			
		||||
		_, err := r.Read(buff)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		content += string(buff);
 | 
			
		||||
		content += string(buff)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = this.LoadString(content);
 | 
			
		||||
	return;
 | 
			
		||||
	err = this.LoadString(content)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// *****************************************************************************
 | 
			
		||||
// *** Satisfy ISaver interface
 | 
			
		||||
// *****************************************************************************
 | 
			
		||||
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 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	defer file.Close();
 | 
			
		||||
	defer file.Close()
 | 
			
		||||
 | 
			
		||||
	content, err  := this.SaveString();
 | 
			
		||||
	content, err := this.SaveString()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	file.Write(strings.Bytes(content));
 | 
			
		||||
	file.Write([]byte(content))
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -265,16 +269,15 @@ func (this *Document) SaveString() (s string, err os.Error) {
 | 
			
		|||
			this.Version, this.Encoding, this.StandAlone)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s += this.Root.String();
 | 
			
		||||
	return;
 | 
			
		||||
	s += this.Root.String()
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Document) SaveStream(w *io.Writer) (err os.Error) {
 | 
			
		||||
	s, err := this.SaveString();
 | 
			
		||||
	s, err := this.SaveString()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	w.Write(strings.Bytes(s));
 | 
			
		||||
	return;
 | 
			
		||||
	w.Write([]byte(s))
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										539
									
								
								src/entitymap.go
									
										
									
									
									
								
							
							
						
						
									
										539
									
								
								src/entitymap.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -5,32 +5,40 @@ import "utf8"
 | 
			
		|||
import "regexp"
 | 
			
		||||
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.
 | 
			
		||||
//    ex: "♣" -> "♣"
 | 
			
		||||
func HtmlToUTF8(entity string) string {
 | 
			
		||||
	// Make sure we have a valid entity: {
 | 
			
		||||
	ok := reg_entity.MatchString(entity);
 | 
			
		||||
	if !ok { return "" }
 | 
			
		||||
	ok := reg_entity.MatchString(entity)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Convert entity to number
 | 
			
		||||
	num, err := strconv.Atoi(entity[2:len(entity)-1]);
 | 
			
		||||
	if err != nil { return "" }
 | 
			
		||||
	num, err := strconv.Atoi(entity[2 : len(entity)-1])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var arr [3]byte;
 | 
			
		||||
	size := utf8.EncodeRune(num, &arr);
 | 
			
		||||
	if size == 0 { return "" }
 | 
			
		||||
	var arr [3]byte
 | 
			
		||||
	size := utf8.EncodeRune(num, &arr)
 | 
			
		||||
	if size == 0 {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return string(&arr);
 | 
			
		||||
	return string(&arr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Converts a single Go utf-token to it's an Html entity.
 | 
			
		||||
//   ex: "♣" -> "♣"
 | 
			
		||||
func UTF8ToHtml(token string) string {
 | 
			
		||||
	rune, size := utf8.DecodeRuneInString(token);
 | 
			
		||||
	if size == 0 { return "" }
 | 
			
		||||
	return fmt.Sprintf("&#%d;", rune);
 | 
			
		||||
	rune, size := utf8.DecodeRuneInString(token)
 | 
			
		||||
	if size == 0 {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("&#%d;", rune)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -48,259 +56,256 @@ func UTF8ToHtml(token string) string {
 | 
			
		|||
	error and abort the parsing. Hence the ability to supply this map.
 | 
			
		||||
*/
 | 
			
		||||
func loadNonStandardEntities(em *map[string]string) {
 | 
			
		||||
	(*em)["pi"] = "\u03c0";
 | 
			
		||||
	(*em)["nabla"] = "\u2207";
 | 
			
		||||
	(*em)["isin"] = "\u2208";
 | 
			
		||||
	(*em)["loz"] = "\u25ca";
 | 
			
		||||
	(*em)["prop"] = "\u221d";
 | 
			
		||||
	(*em)["para"] = "\u00b6";
 | 
			
		||||
	(*em)["Aring"] = "\u00c5";
 | 
			
		||||
	(*em)["euro"] = "\u20ac";
 | 
			
		||||
	(*em)["sup3"] = "\u00b3";
 | 
			
		||||
	(*em)["sup2"] = "\u00b2";
 | 
			
		||||
	(*em)["sup1"] = "\u00b9";
 | 
			
		||||
	(*em)["prod"] = "\u220f";
 | 
			
		||||
	(*em)["gamma"] = "\u03b3";
 | 
			
		||||
	(*em)["perp"] = "\u22a5";
 | 
			
		||||
	(*em)["lfloor"] = "\u230a";
 | 
			
		||||
	(*em)["fnof"] = "\u0192";
 | 
			
		||||
	(*em)["frasl"] = "\u2044";
 | 
			
		||||
	(*em)["rlm"] = "\u200f";
 | 
			
		||||
	(*em)["omega"] = "\u03c9";
 | 
			
		||||
	(*em)["part"] = "\u2202";
 | 
			
		||||
	(*em)["euml"] = "\u00eb";
 | 
			
		||||
	(*em)["Kappa"] = "\u039a";
 | 
			
		||||
	(*em)["nbsp"] = "\u00a0";
 | 
			
		||||
	(*em)["Eacute"] = "\u00c9";
 | 
			
		||||
	(*em)["brvbar"] = "\u00a6";
 | 
			
		||||
	(*em)["otimes"] = "\u2297";
 | 
			
		||||
	(*em)["ndash"] = "\u2013";
 | 
			
		||||
	(*em)["thinsp"] = "\u2009";
 | 
			
		||||
	(*em)["nu"] = "\u03bd";
 | 
			
		||||
	(*em)["Upsilon"] = "\u03a5";
 | 
			
		||||
	(*em)["upsih"] = "\u03d2";
 | 
			
		||||
	(*em)["raquo"] = "\u00bb";
 | 
			
		||||
	(*em)["yacute"] = "\u00fd";
 | 
			
		||||
	(*em)["delta"] = "\u03b4";
 | 
			
		||||
	(*em)["eth"] = "\u00f0";
 | 
			
		||||
	(*em)["supe"] = "\u2287";
 | 
			
		||||
	(*em)["ne"] = "\u2260";
 | 
			
		||||
	(*em)["ni"] = "\u220b";
 | 
			
		||||
	(*em)["eta"] = "\u03b7";
 | 
			
		||||
	(*em)["uArr"] = "\u21d1";
 | 
			
		||||
	(*em)["image"] = "\u2111";
 | 
			
		||||
	(*em)["asymp"] = "\u2248";
 | 
			
		||||
	(*em)["oacute"] = "\u00f3";
 | 
			
		||||
	(*em)["rarr"] = "\u2192";
 | 
			
		||||
	(*em)["emsp"] = "\u2003";
 | 
			
		||||
	(*em)["acirc"] = "\u00e2";
 | 
			
		||||
	(*em)["shy"] = "\u00ad";
 | 
			
		||||
	(*em)["yuml"] = "\u00ff";
 | 
			
		||||
	(*em)["acute"] = "\u00b4";
 | 
			
		||||
	(*em)["int"] = "\u222b";
 | 
			
		||||
	(*em)["ccedil"] = "\u00e7";
 | 
			
		||||
	(*em)["Acirc"] = "\u00c2";
 | 
			
		||||
	(*em)["Ograve"] = "\u00d2";
 | 
			
		||||
	(*em)["times"] = "\u00d7";
 | 
			
		||||
	(*em)["weierp"] = "\u2118";
 | 
			
		||||
	(*em)["Tau"] = "\u03a4";
 | 
			
		||||
	(*em)["omicron"] = "\u03bf";
 | 
			
		||||
	(*em)["lt"] = "\u003c";
 | 
			
		||||
	(*em)["Mu"] = "\u039c";
 | 
			
		||||
	(*em)["Ucirc"] = "\u00db";
 | 
			
		||||
	(*em)["sub"] = "\u2282";
 | 
			
		||||
	(*em)["le"] = "\u2264";
 | 
			
		||||
	(*em)["sum"] = "\u2211";
 | 
			
		||||
	(*em)["sup"] = "\u2283";
 | 
			
		||||
	(*em)["lrm"] = "\u200e";
 | 
			
		||||
	(*em)["frac34"] = "\u00be";
 | 
			
		||||
	(*em)["Iota"] = "\u0399";
 | 
			
		||||
	(*em)["Ugrave"] = "\u00d9";
 | 
			
		||||
	(*em)["THORN"] = "\u00de";
 | 
			
		||||
	(*em)["rsaquo"] = "\u203a";
 | 
			
		||||
	(*em)["not"] = "\u00ac";
 | 
			
		||||
	(*em)["sigma"] = "\u03c3";
 | 
			
		||||
	(*em)["iuml"] = "\u00ef";
 | 
			
		||||
	(*em)["epsilon"] = "\u03b5";
 | 
			
		||||
	(*em)["spades"] = "\u2660";
 | 
			
		||||
	(*em)["theta"] = "\u03b8";
 | 
			
		||||
	(*em)["divide"] = "\u00f7";
 | 
			
		||||
	(*em)["Atilde"] = "\u00c3";
 | 
			
		||||
	(*em)["uacute"] = "\u00fa";
 | 
			
		||||
	(*em)["Rho"] = "\u03a1";
 | 
			
		||||
	(*em)["trade"] = "\u2122";
 | 
			
		||||
	(*em)["chi"] = "\u03c7";
 | 
			
		||||
	(*em)["agrave"] = "\u00e0";
 | 
			
		||||
	(*em)["or"] = "\u2228";
 | 
			
		||||
	(*em)["circ"] = "\u02c6";
 | 
			
		||||
	(*em)["middot"] = "\u00b7";
 | 
			
		||||
	(*em)["plusmn"] = "\u00b1";
 | 
			
		||||
	(*em)["aring"] = "\u00e5";
 | 
			
		||||
	(*em)["lsquo"] = "\u2018";
 | 
			
		||||
	(*em)["Yacute"] = "\u00dd";
 | 
			
		||||
	(*em)["oline"] = "\u203e";
 | 
			
		||||
	(*em)["copy"] = "\u00a9";
 | 
			
		||||
	(*em)["icirc"] = "\u00ee";
 | 
			
		||||
	(*em)["lowast"] = "\u2217";
 | 
			
		||||
	(*em)["Oacute"] = "\u00d3";
 | 
			
		||||
	(*em)["aacute"] = "\u00e1";
 | 
			
		||||
	(*em)["oplus"] = "\u2295";
 | 
			
		||||
	(*em)["crarr"] = "\u21b5";
 | 
			
		||||
	(*em)["thetasym"] = "\u03d1";
 | 
			
		||||
	(*em)["Beta"] = "\u0392";
 | 
			
		||||
	(*em)["laquo"] = "\u00ab";
 | 
			
		||||
	(*em)["rang"] = "\u232a";
 | 
			
		||||
	(*em)["tilde"] = "\u02dc";
 | 
			
		||||
	(*em)["Uuml"] = "\u00dc";
 | 
			
		||||
	(*em)["zwj"] = "\u200d";
 | 
			
		||||
	(*em)["mu"] = "\u03bc";
 | 
			
		||||
	(*em)["Ccedil"] = "\u00c7";
 | 
			
		||||
	(*em)["infin"] = "\u221e";
 | 
			
		||||
	(*em)["ouml"] = "\u00f6";
 | 
			
		||||
	(*em)["rfloor"] = "\u230b";
 | 
			
		||||
	(*em)["pound"] = "\u00a3";
 | 
			
		||||
	(*em)["szlig"] = "\u00df";
 | 
			
		||||
	(*em)["thorn"] = "\u00fe";
 | 
			
		||||
	(*em)["forall"] = "\u2200";
 | 
			
		||||
	(*em)["piv"] = "\u03d6";
 | 
			
		||||
	(*em)["rdquo"] = "\u201d";
 | 
			
		||||
	(*em)["frac12"] = "\u00bd";
 | 
			
		||||
	(*em)["frac14"] = "\u00bc";
 | 
			
		||||
	(*em)["Ocirc"] = "\u00d4";
 | 
			
		||||
	(*em)["Ecirc"] = "\u00ca";
 | 
			
		||||
	(*em)["kappa"] = "\u03ba";
 | 
			
		||||
	(*em)["Euml"] = "\u00cb";
 | 
			
		||||
	(*em)["minus"] = "\u2212";
 | 
			
		||||
	(*em)["cong"] = "\u2245";
 | 
			
		||||
	(*em)["hellip"] = "\u2026";
 | 
			
		||||
	(*em)["equiv"] = "\u2261";
 | 
			
		||||
	(*em)["cent"] = "\u00a2";
 | 
			
		||||
	(*em)["Uacute"] = "\u00da";
 | 
			
		||||
	(*em)["darr"] = "\u2193";
 | 
			
		||||
	(*em)["Eta"] = "\u0397";
 | 
			
		||||
	(*em)["sbquo"] = "\u201a";
 | 
			
		||||
	(*em)["rArr"] = "\u21d2";
 | 
			
		||||
	(*em)["igrave"] = "\u00ec";
 | 
			
		||||
	(*em)["uml"] = "\u00a8";
 | 
			
		||||
	(*em)["lambda"] = "\u03bb";
 | 
			
		||||
	(*em)["oelig"] = "\u0153";
 | 
			
		||||
	(*em)["harr"] = "\u2194";
 | 
			
		||||
	(*em)["ang"] = "\u2220";
 | 
			
		||||
	(*em)["clubs"] = "\u2663";
 | 
			
		||||
	(*em)["and"] = "\u2227";
 | 
			
		||||
	(*em)["permil"] = "\u2030";
 | 
			
		||||
	(*em)["larr"] = "\u2190";
 | 
			
		||||
	(*em)["Yuml"] = "\u0178";
 | 
			
		||||
	(*em)["cup"] = "\u222a";
 | 
			
		||||
	(*em)["Xi"] = "\u039e";
 | 
			
		||||
	(*em)["Alpha"] = "\u0391";
 | 
			
		||||
	(*em)["phi"] = "\u03c6";
 | 
			
		||||
	(*em)["ucirc"] = "\u00fb";
 | 
			
		||||
	(*em)["oslash"] = "\u00f8";
 | 
			
		||||
	(*em)["rsquo"] = "\u2019";
 | 
			
		||||
	(*em)["AElig"] = "\u00c6";
 | 
			
		||||
	(*em)["mdash"] = "\u2014";
 | 
			
		||||
	(*em)["psi"] = "\u03c8";
 | 
			
		||||
	(*em)["eacute"] = "\u00e9";
 | 
			
		||||
	(*em)["otilde"] = "\u00f5";
 | 
			
		||||
	(*em)["yen"] = "\u00a5";
 | 
			
		||||
	(*em)["gt"] = "\u003e";
 | 
			
		||||
	(*em)["Iuml"] = "\u00cf";
 | 
			
		||||
	(*em)["Prime"] = "\u2033";
 | 
			
		||||
	(*em)["Chi"] = "\u03a7";
 | 
			
		||||
	(*em)["ge"] = "\u2265";
 | 
			
		||||
	(*em)["reg"] = "\u00ae";
 | 
			
		||||
	(*em)["hearts"] = "\u2665";
 | 
			
		||||
	(*em)["auml"] = "\u00e4";
 | 
			
		||||
	(*em)["Agrave"] = "\u00c0";
 | 
			
		||||
	(*em)["sect"] = "\u00a7";
 | 
			
		||||
	(*em)["sube"] = "\u2286";
 | 
			
		||||
	(*em)["sigmaf"] = "\u03c2";
 | 
			
		||||
	(*em)["Gamma"] = "\u0393";
 | 
			
		||||
	(*em)["amp"] = "\u0026";
 | 
			
		||||
	(*em)["ensp"] = "\u2002";
 | 
			
		||||
	(*em)["ETH"] = "\u00d0";
 | 
			
		||||
	(*em)["Igrave"] = "\u00cc";
 | 
			
		||||
	(*em)["Omega"] = "\u03a9";
 | 
			
		||||
	(*em)["Lambda"] = "\u039b";
 | 
			
		||||
	(*em)["Omicron"] = "\u039f";
 | 
			
		||||
	(*em)["there4"] = "\u2234";
 | 
			
		||||
	(*em)["ntilde"] = "\u00f1";
 | 
			
		||||
	(*em)["xi"] = "\u03be";
 | 
			
		||||
	(*em)["dagger"] = "\u2020";
 | 
			
		||||
	(*em)["egrave"] = "\u00e8";
 | 
			
		||||
	(*em)["Delta"] = "\u0394";
 | 
			
		||||
	(*em)["OElig"] = "\u0152";
 | 
			
		||||
	(*em)["diams"] = "\u2666";
 | 
			
		||||
	(*em)["ldquo"] = "\u201c";
 | 
			
		||||
	(*em)["radic"] = "\u221a";
 | 
			
		||||
	(*em)["Oslash"] = "\u00d8";
 | 
			
		||||
	(*em)["Ouml"] = "\u00d6";
 | 
			
		||||
	(*em)["lceil"] = "\u2308";
 | 
			
		||||
	(*em)["uarr"] = "\u2191";
 | 
			
		||||
	(*em)["atilde"] = "\u00e3";
 | 
			
		||||
	(*em)["iquest"] = "\u00bf";
 | 
			
		||||
	(*em)["lsaquo"] = "\u2039";
 | 
			
		||||
	(*em)["Epsilon"] = "\u0395";
 | 
			
		||||
	(*em)["iacute"] = "\u00ed";
 | 
			
		||||
	(*em)["cap"] = "\u2229";
 | 
			
		||||
	(*em)["deg"] = "\u00b0";
 | 
			
		||||
	(*em)["Otilde"] = "\u00d5";
 | 
			
		||||
	(*em)["zeta"] = "\u03b6";
 | 
			
		||||
	(*em)["ocirc"] = "\u00f4";
 | 
			
		||||
	(*em)["scaron"] = "\u0161";
 | 
			
		||||
	(*em)["ecirc"] = "\u00ea";
 | 
			
		||||
	(*em)["ordm"] = "\u00ba";
 | 
			
		||||
	(*em)["tau"] = "\u03c4";
 | 
			
		||||
	(*em)["Auml"] = "\u00c4";
 | 
			
		||||
	(*em)["dArr"] = "\u21d3";
 | 
			
		||||
	(*em)["ordf"] = "\u00aa";
 | 
			
		||||
	(*em)["alefsym"] = "\u2135";
 | 
			
		||||
	(*em)["notin"] = "\u2209";
 | 
			
		||||
	(*em)["Pi"] = "\u03a0";
 | 
			
		||||
	(*em)["sdot"] = "\u22c5";
 | 
			
		||||
	(*em)["upsilon"] = "\u03c5";
 | 
			
		||||
	(*em)["iota"] = "\u03b9";
 | 
			
		||||
	(*em)["hArr"] = "\u21d4";
 | 
			
		||||
	(*em)["Sigma"] = "\u03a3";
 | 
			
		||||
	(*em)["lang"] = "\u2329";
 | 
			
		||||
	(*em)["curren"] = "\u00a4";
 | 
			
		||||
	(*em)["Theta"] = "\u0398";
 | 
			
		||||
	(*em)["lArr"] = "\u21d0";
 | 
			
		||||
	(*em)["Phi"] = "\u03a6";
 | 
			
		||||
	(*em)["Nu"] = "\u039d";
 | 
			
		||||
	(*em)["rho"] = "\u03c1";
 | 
			
		||||
	(*em)["alpha"] = "\u03b1";
 | 
			
		||||
	(*em)["iexcl"] = "\u00a1";
 | 
			
		||||
	(*em)["micro"] = "\u00b5";
 | 
			
		||||
	(*em)["cedil"] = "\u00b8";
 | 
			
		||||
	(*em)["Ntilde"] = "\u00d1";
 | 
			
		||||
	(*em)["Psi"] = "\u03a8";
 | 
			
		||||
	(*em)["Dagger"] = "\u2021";
 | 
			
		||||
	(*em)["Egrave"] = "\u00c8";
 | 
			
		||||
	(*em)["Icirc"] = "\u00ce";
 | 
			
		||||
	(*em)["nsub"] = "\u2284";
 | 
			
		||||
	(*em)["bdquo"] = "\u201e";
 | 
			
		||||
	(*em)["empty"] = "\u2205";
 | 
			
		||||
	(*em)["aelig"] = "\u00e6";
 | 
			
		||||
	(*em)["ograve"] = "\u00f2";
 | 
			
		||||
	(*em)["macr"] = "\u00af";
 | 
			
		||||
	(*em)["Zeta"] = "\u0396";
 | 
			
		||||
	(*em)["beta"] = "\u03b2";
 | 
			
		||||
	(*em)["sim"] = "\u223c";
 | 
			
		||||
	(*em)["uuml"] = "\u00fc";
 | 
			
		||||
	(*em)["Aacute"] = "\u00c1";
 | 
			
		||||
	(*em)["Iacute"] = "\u00cd";
 | 
			
		||||
	(*em)["exist"] = "\u2203";
 | 
			
		||||
	(*em)["prime"] = "\u2032";
 | 
			
		||||
	(*em)["rceil"] = "\u2309";
 | 
			
		||||
	(*em)["real"] = "\u211c";
 | 
			
		||||
	(*em)["zwnj"] = "\u200c";
 | 
			
		||||
	(*em)["bull"] = "\u2022";
 | 
			
		||||
	(*em)["quot"] = "\u0022";
 | 
			
		||||
	(*em)["Scaron"] = "\u0160";
 | 
			
		||||
	(*em)["ugrave"] = "\u00f9";
 | 
			
		||||
	(*em)["pi"] = "\u03c0"
 | 
			
		||||
	(*em)["nabla"] = "\u2207"
 | 
			
		||||
	(*em)["isin"] = "\u2208"
 | 
			
		||||
	(*em)["loz"] = "\u25ca"
 | 
			
		||||
	(*em)["prop"] = "\u221d"
 | 
			
		||||
	(*em)["para"] = "\u00b6"
 | 
			
		||||
	(*em)["Aring"] = "\u00c5"
 | 
			
		||||
	(*em)["euro"] = "\u20ac"
 | 
			
		||||
	(*em)["sup3"] = "\u00b3"
 | 
			
		||||
	(*em)["sup2"] = "\u00b2"
 | 
			
		||||
	(*em)["sup1"] = "\u00b9"
 | 
			
		||||
	(*em)["prod"] = "\u220f"
 | 
			
		||||
	(*em)["gamma"] = "\u03b3"
 | 
			
		||||
	(*em)["perp"] = "\u22a5"
 | 
			
		||||
	(*em)["lfloor"] = "\u230a"
 | 
			
		||||
	(*em)["fnof"] = "\u0192"
 | 
			
		||||
	(*em)["frasl"] = "\u2044"
 | 
			
		||||
	(*em)["rlm"] = "\u200f"
 | 
			
		||||
	(*em)["omega"] = "\u03c9"
 | 
			
		||||
	(*em)["part"] = "\u2202"
 | 
			
		||||
	(*em)["euml"] = "\u00eb"
 | 
			
		||||
	(*em)["Kappa"] = "\u039a"
 | 
			
		||||
	(*em)["nbsp"] = "\u00a0"
 | 
			
		||||
	(*em)["Eacute"] = "\u00c9"
 | 
			
		||||
	(*em)["brvbar"] = "\u00a6"
 | 
			
		||||
	(*em)["otimes"] = "\u2297"
 | 
			
		||||
	(*em)["ndash"] = "\u2013"
 | 
			
		||||
	(*em)["thinsp"] = "\u2009"
 | 
			
		||||
	(*em)["nu"] = "\u03bd"
 | 
			
		||||
	(*em)["Upsilon"] = "\u03a5"
 | 
			
		||||
	(*em)["upsih"] = "\u03d2"
 | 
			
		||||
	(*em)["raquo"] = "\u00bb"
 | 
			
		||||
	(*em)["yacute"] = "\u00fd"
 | 
			
		||||
	(*em)["delta"] = "\u03b4"
 | 
			
		||||
	(*em)["eth"] = "\u00f0"
 | 
			
		||||
	(*em)["supe"] = "\u2287"
 | 
			
		||||
	(*em)["ne"] = "\u2260"
 | 
			
		||||
	(*em)["ni"] = "\u220b"
 | 
			
		||||
	(*em)["eta"] = "\u03b7"
 | 
			
		||||
	(*em)["uArr"] = "\u21d1"
 | 
			
		||||
	(*em)["image"] = "\u2111"
 | 
			
		||||
	(*em)["asymp"] = "\u2248"
 | 
			
		||||
	(*em)["oacute"] = "\u00f3"
 | 
			
		||||
	(*em)["rarr"] = "\u2192"
 | 
			
		||||
	(*em)["emsp"] = "\u2003"
 | 
			
		||||
	(*em)["acirc"] = "\u00e2"
 | 
			
		||||
	(*em)["shy"] = "\u00ad"
 | 
			
		||||
	(*em)["yuml"] = "\u00ff"
 | 
			
		||||
	(*em)["acute"] = "\u00b4"
 | 
			
		||||
	(*em)["int"] = "\u222b"
 | 
			
		||||
	(*em)["ccedil"] = "\u00e7"
 | 
			
		||||
	(*em)["Acirc"] = "\u00c2"
 | 
			
		||||
	(*em)["Ograve"] = "\u00d2"
 | 
			
		||||
	(*em)["times"] = "\u00d7"
 | 
			
		||||
	(*em)["weierp"] = "\u2118"
 | 
			
		||||
	(*em)["Tau"] = "\u03a4"
 | 
			
		||||
	(*em)["omicron"] = "\u03bf"
 | 
			
		||||
	(*em)["lt"] = "\u003c"
 | 
			
		||||
	(*em)["Mu"] = "\u039c"
 | 
			
		||||
	(*em)["Ucirc"] = "\u00db"
 | 
			
		||||
	(*em)["sub"] = "\u2282"
 | 
			
		||||
	(*em)["le"] = "\u2264"
 | 
			
		||||
	(*em)["sum"] = "\u2211"
 | 
			
		||||
	(*em)["sup"] = "\u2283"
 | 
			
		||||
	(*em)["lrm"] = "\u200e"
 | 
			
		||||
	(*em)["frac34"] = "\u00be"
 | 
			
		||||
	(*em)["Iota"] = "\u0399"
 | 
			
		||||
	(*em)["Ugrave"] = "\u00d9"
 | 
			
		||||
	(*em)["THORN"] = "\u00de"
 | 
			
		||||
	(*em)["rsaquo"] = "\u203a"
 | 
			
		||||
	(*em)["not"] = "\u00ac"
 | 
			
		||||
	(*em)["sigma"] = "\u03c3"
 | 
			
		||||
	(*em)["iuml"] = "\u00ef"
 | 
			
		||||
	(*em)["epsilon"] = "\u03b5"
 | 
			
		||||
	(*em)["spades"] = "\u2660"
 | 
			
		||||
	(*em)["theta"] = "\u03b8"
 | 
			
		||||
	(*em)["divide"] = "\u00f7"
 | 
			
		||||
	(*em)["Atilde"] = "\u00c3"
 | 
			
		||||
	(*em)["uacute"] = "\u00fa"
 | 
			
		||||
	(*em)["Rho"] = "\u03a1"
 | 
			
		||||
	(*em)["trade"] = "\u2122"
 | 
			
		||||
	(*em)["chi"] = "\u03c7"
 | 
			
		||||
	(*em)["agrave"] = "\u00e0"
 | 
			
		||||
	(*em)["or"] = "\u2228"
 | 
			
		||||
	(*em)["circ"] = "\u02c6"
 | 
			
		||||
	(*em)["middot"] = "\u00b7"
 | 
			
		||||
	(*em)["plusmn"] = "\u00b1"
 | 
			
		||||
	(*em)["aring"] = "\u00e5"
 | 
			
		||||
	(*em)["lsquo"] = "\u2018"
 | 
			
		||||
	(*em)["Yacute"] = "\u00dd"
 | 
			
		||||
	(*em)["oline"] = "\u203e"
 | 
			
		||||
	(*em)["copy"] = "\u00a9"
 | 
			
		||||
	(*em)["icirc"] = "\u00ee"
 | 
			
		||||
	(*em)["lowast"] = "\u2217"
 | 
			
		||||
	(*em)["Oacute"] = "\u00d3"
 | 
			
		||||
	(*em)["aacute"] = "\u00e1"
 | 
			
		||||
	(*em)["oplus"] = "\u2295"
 | 
			
		||||
	(*em)["crarr"] = "\u21b5"
 | 
			
		||||
	(*em)["thetasym"] = "\u03d1"
 | 
			
		||||
	(*em)["Beta"] = "\u0392"
 | 
			
		||||
	(*em)["laquo"] = "\u00ab"
 | 
			
		||||
	(*em)["rang"] = "\u232a"
 | 
			
		||||
	(*em)["tilde"] = "\u02dc"
 | 
			
		||||
	(*em)["Uuml"] = "\u00dc"
 | 
			
		||||
	(*em)["zwj"] = "\u200d"
 | 
			
		||||
	(*em)["mu"] = "\u03bc"
 | 
			
		||||
	(*em)["Ccedil"] = "\u00c7"
 | 
			
		||||
	(*em)["infin"] = "\u221e"
 | 
			
		||||
	(*em)["ouml"] = "\u00f6"
 | 
			
		||||
	(*em)["rfloor"] = "\u230b"
 | 
			
		||||
	(*em)["pound"] = "\u00a3"
 | 
			
		||||
	(*em)["szlig"] = "\u00df"
 | 
			
		||||
	(*em)["thorn"] = "\u00fe"
 | 
			
		||||
	(*em)["forall"] = "\u2200"
 | 
			
		||||
	(*em)["piv"] = "\u03d6"
 | 
			
		||||
	(*em)["rdquo"] = "\u201d"
 | 
			
		||||
	(*em)["frac12"] = "\u00bd"
 | 
			
		||||
	(*em)["frac14"] = "\u00bc"
 | 
			
		||||
	(*em)["Ocirc"] = "\u00d4"
 | 
			
		||||
	(*em)["Ecirc"] = "\u00ca"
 | 
			
		||||
	(*em)["kappa"] = "\u03ba"
 | 
			
		||||
	(*em)["Euml"] = "\u00cb"
 | 
			
		||||
	(*em)["minus"] = "\u2212"
 | 
			
		||||
	(*em)["cong"] = "\u2245"
 | 
			
		||||
	(*em)["hellip"] = "\u2026"
 | 
			
		||||
	(*em)["equiv"] = "\u2261"
 | 
			
		||||
	(*em)["cent"] = "\u00a2"
 | 
			
		||||
	(*em)["Uacute"] = "\u00da"
 | 
			
		||||
	(*em)["darr"] = "\u2193"
 | 
			
		||||
	(*em)["Eta"] = "\u0397"
 | 
			
		||||
	(*em)["sbquo"] = "\u201a"
 | 
			
		||||
	(*em)["rArr"] = "\u21d2"
 | 
			
		||||
	(*em)["igrave"] = "\u00ec"
 | 
			
		||||
	(*em)["uml"] = "\u00a8"
 | 
			
		||||
	(*em)["lambda"] = "\u03bb"
 | 
			
		||||
	(*em)["oelig"] = "\u0153"
 | 
			
		||||
	(*em)["harr"] = "\u2194"
 | 
			
		||||
	(*em)["ang"] = "\u2220"
 | 
			
		||||
	(*em)["clubs"] = "\u2663"
 | 
			
		||||
	(*em)["and"] = "\u2227"
 | 
			
		||||
	(*em)["permil"] = "\u2030"
 | 
			
		||||
	(*em)["larr"] = "\u2190"
 | 
			
		||||
	(*em)["Yuml"] = "\u0178"
 | 
			
		||||
	(*em)["cup"] = "\u222a"
 | 
			
		||||
	(*em)["Xi"] = "\u039e"
 | 
			
		||||
	(*em)["Alpha"] = "\u0391"
 | 
			
		||||
	(*em)["phi"] = "\u03c6"
 | 
			
		||||
	(*em)["ucirc"] = "\u00fb"
 | 
			
		||||
	(*em)["oslash"] = "\u00f8"
 | 
			
		||||
	(*em)["rsquo"] = "\u2019"
 | 
			
		||||
	(*em)["AElig"] = "\u00c6"
 | 
			
		||||
	(*em)["mdash"] = "\u2014"
 | 
			
		||||
	(*em)["psi"] = "\u03c8"
 | 
			
		||||
	(*em)["eacute"] = "\u00e9"
 | 
			
		||||
	(*em)["otilde"] = "\u00f5"
 | 
			
		||||
	(*em)["yen"] = "\u00a5"
 | 
			
		||||
	(*em)["gt"] = "\u003e"
 | 
			
		||||
	(*em)["Iuml"] = "\u00cf"
 | 
			
		||||
	(*em)["Prime"] = "\u2033"
 | 
			
		||||
	(*em)["Chi"] = "\u03a7"
 | 
			
		||||
	(*em)["ge"] = "\u2265"
 | 
			
		||||
	(*em)["reg"] = "\u00ae"
 | 
			
		||||
	(*em)["hearts"] = "\u2665"
 | 
			
		||||
	(*em)["auml"] = "\u00e4"
 | 
			
		||||
	(*em)["Agrave"] = "\u00c0"
 | 
			
		||||
	(*em)["sect"] = "\u00a7"
 | 
			
		||||
	(*em)["sube"] = "\u2286"
 | 
			
		||||
	(*em)["sigmaf"] = "\u03c2"
 | 
			
		||||
	(*em)["Gamma"] = "\u0393"
 | 
			
		||||
	(*em)["amp"] = "\u0026"
 | 
			
		||||
	(*em)["ensp"] = "\u2002"
 | 
			
		||||
	(*em)["ETH"] = "\u00d0"
 | 
			
		||||
	(*em)["Igrave"] = "\u00cc"
 | 
			
		||||
	(*em)["Omega"] = "\u03a9"
 | 
			
		||||
	(*em)["Lambda"] = "\u039b"
 | 
			
		||||
	(*em)["Omicron"] = "\u039f"
 | 
			
		||||
	(*em)["there4"] = "\u2234"
 | 
			
		||||
	(*em)["ntilde"] = "\u00f1"
 | 
			
		||||
	(*em)["xi"] = "\u03be"
 | 
			
		||||
	(*em)["dagger"] = "\u2020"
 | 
			
		||||
	(*em)["egrave"] = "\u00e8"
 | 
			
		||||
	(*em)["Delta"] = "\u0394"
 | 
			
		||||
	(*em)["OElig"] = "\u0152"
 | 
			
		||||
	(*em)["diams"] = "\u2666"
 | 
			
		||||
	(*em)["ldquo"] = "\u201c"
 | 
			
		||||
	(*em)["radic"] = "\u221a"
 | 
			
		||||
	(*em)["Oslash"] = "\u00d8"
 | 
			
		||||
	(*em)["Ouml"] = "\u00d6"
 | 
			
		||||
	(*em)["lceil"] = "\u2308"
 | 
			
		||||
	(*em)["uarr"] = "\u2191"
 | 
			
		||||
	(*em)["atilde"] = "\u00e3"
 | 
			
		||||
	(*em)["iquest"] = "\u00bf"
 | 
			
		||||
	(*em)["lsaquo"] = "\u2039"
 | 
			
		||||
	(*em)["Epsilon"] = "\u0395"
 | 
			
		||||
	(*em)["iacute"] = "\u00ed"
 | 
			
		||||
	(*em)["cap"] = "\u2229"
 | 
			
		||||
	(*em)["deg"] = "\u00b0"
 | 
			
		||||
	(*em)["Otilde"] = "\u00d5"
 | 
			
		||||
	(*em)["zeta"] = "\u03b6"
 | 
			
		||||
	(*em)["ocirc"] = "\u00f4"
 | 
			
		||||
	(*em)["scaron"] = "\u0161"
 | 
			
		||||
	(*em)["ecirc"] = "\u00ea"
 | 
			
		||||
	(*em)["ordm"] = "\u00ba"
 | 
			
		||||
	(*em)["tau"] = "\u03c4"
 | 
			
		||||
	(*em)["Auml"] = "\u00c4"
 | 
			
		||||
	(*em)["dArr"] = "\u21d3"
 | 
			
		||||
	(*em)["ordf"] = "\u00aa"
 | 
			
		||||
	(*em)["alefsym"] = "\u2135"
 | 
			
		||||
	(*em)["notin"] = "\u2209"
 | 
			
		||||
	(*em)["Pi"] = "\u03a0"
 | 
			
		||||
	(*em)["sdot"] = "\u22c5"
 | 
			
		||||
	(*em)["upsilon"] = "\u03c5"
 | 
			
		||||
	(*em)["iota"] = "\u03b9"
 | 
			
		||||
	(*em)["hArr"] = "\u21d4"
 | 
			
		||||
	(*em)["Sigma"] = "\u03a3"
 | 
			
		||||
	(*em)["lang"] = "\u2329"
 | 
			
		||||
	(*em)["curren"] = "\u00a4"
 | 
			
		||||
	(*em)["Theta"] = "\u0398"
 | 
			
		||||
	(*em)["lArr"] = "\u21d0"
 | 
			
		||||
	(*em)["Phi"] = "\u03a6"
 | 
			
		||||
	(*em)["Nu"] = "\u039d"
 | 
			
		||||
	(*em)["rho"] = "\u03c1"
 | 
			
		||||
	(*em)["alpha"] = "\u03b1"
 | 
			
		||||
	(*em)["iexcl"] = "\u00a1"
 | 
			
		||||
	(*em)["micro"] = "\u00b5"
 | 
			
		||||
	(*em)["cedil"] = "\u00b8"
 | 
			
		||||
	(*em)["Ntilde"] = "\u00d1"
 | 
			
		||||
	(*em)["Psi"] = "\u03a8"
 | 
			
		||||
	(*em)["Dagger"] = "\u2021"
 | 
			
		||||
	(*em)["Egrave"] = "\u00c8"
 | 
			
		||||
	(*em)["Icirc"] = "\u00ce"
 | 
			
		||||
	(*em)["nsub"] = "\u2284"
 | 
			
		||||
	(*em)["bdquo"] = "\u201e"
 | 
			
		||||
	(*em)["empty"] = "\u2205"
 | 
			
		||||
	(*em)["aelig"] = "\u00e6"
 | 
			
		||||
	(*em)["ograve"] = "\u00f2"
 | 
			
		||||
	(*em)["macr"] = "\u00af"
 | 
			
		||||
	(*em)["Zeta"] = "\u0396"
 | 
			
		||||
	(*em)["beta"] = "\u03b2"
 | 
			
		||||
	(*em)["sim"] = "\u223c"
 | 
			
		||||
	(*em)["uuml"] = "\u00fc"
 | 
			
		||||
	(*em)["Aacute"] = "\u00c1"
 | 
			
		||||
	(*em)["Iacute"] = "\u00cd"
 | 
			
		||||
	(*em)["exist"] = "\u2203"
 | 
			
		||||
	(*em)["prime"] = "\u2032"
 | 
			
		||||
	(*em)["rceil"] = "\u2309"
 | 
			
		||||
	(*em)["real"] = "\u211c"
 | 
			
		||||
	(*em)["zwnj"] = "\u200c"
 | 
			
		||||
	(*em)["bull"] = "\u2022"
 | 
			
		||||
	(*em)["quot"] = "\u0022"
 | 
			
		||||
	(*em)["Scaron"] = "\u0160"
 | 
			
		||||
	(*em)["ugrave"] = "\u00f9"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										18
									
								
								src/io.go
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								src/io.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -4,19 +4,19 @@ import "os"
 | 
			
		|||
import "io"
 | 
			
		||||
 | 
			
		||||
type ILoader interface {
 | 
			
		||||
	LoadUrl(string) os.Error;
 | 
			
		||||
	LoadFile(string) os.Error;
 | 
			
		||||
	LoadString(string) os.Error;
 | 
			
		||||
	LoadStream(*io.Reader) os.Error;
 | 
			
		||||
	LoadUrl(string) os.Error
 | 
			
		||||
	LoadFile(string) os.Error
 | 
			
		||||
	LoadString(string) os.Error
 | 
			
		||||
	LoadStream(*io.Reader) os.Error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ISaver interface {
 | 
			
		||||
	SaveFile(string) os.Error;
 | 
			
		||||
	SaveString(string) (string, os.Error);
 | 
			
		||||
	SaveStream(*io.Writer) os.Error;
 | 
			
		||||
	SaveFile(string) os.Error
 | 
			
		||||
	SaveString(string) (string, os.Error)
 | 
			
		||||
	SaveStream(*io.Writer) os.Error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ILoaderSaver interface {
 | 
			
		||||
	ILoader;
 | 
			
		||||
	ISaver;
 | 
			
		||||
	ILoader
 | 
			
		||||
	ISaver
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										300
									
								
								src/node.go
									
										
									
									
									
								
							
							
						
						
									
										300
									
								
								src/node.go
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -7,26 +7,26 @@ import "fmt"
 | 
			
		|||
import "strconv"
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	NT_ROOT		= 0x00;
 | 
			
		||||
	NT_DIRECTIVE	= 0x01;
 | 
			
		||||
	NT_PROCINST	= 0x02;
 | 
			
		||||
	NT_COMMENT	= 0x03;
 | 
			
		||||
	NT_ELEMENT	= 0x04;
 | 
			
		||||
	NT_ROOT      = 0x00
 | 
			
		||||
	NT_DIRECTIVE = 0x01
 | 
			
		||||
	NT_PROCINST  = 0x02
 | 
			
		||||
	NT_COMMENT   = 0x03
 | 
			
		||||
	NT_ELEMENT   = 0x04
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Attr struct {
 | 
			
		||||
	Name	xml.Name;
 | 
			
		||||
	Value	string;
 | 
			
		||||
	Name  xml.Name
 | 
			
		||||
	Value string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Node struct {
 | 
			
		||||
	Type		byte;
 | 
			
		||||
	Name		xml.Name;
 | 
			
		||||
	Children	[]*Node;
 | 
			
		||||
	Attributes	[]Attr;
 | 
			
		||||
	Parent		*Node;
 | 
			
		||||
	Value		string;
 | 
			
		||||
	Target		string; // procinst field
 | 
			
		||||
	Type       byte
 | 
			
		||||
	Name       xml.Name
 | 
			
		||||
	Children   []*Node
 | 
			
		||||
	Attributes []Attr
 | 
			
		||||
	Parent     *Node
 | 
			
		||||
	Value      string
 | 
			
		||||
	Target     string // procinst field
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewNode(tid byte) *Node { return &Node{Type: tid} }
 | 
			
		||||
| 
						 | 
				
			
			@ -34,143 +34,187 @@ func NewNode(tid byte) *Node	{ return &Node{Type: tid} }
 | 
			
		|||
// This wraps the standard xml.Unmarshal function and supplies this particular
 | 
			
		||||
// node as the content to be unmarshalled.
 | 
			
		||||
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
 | 
			
		||||
func (this *Node) GetValue(namespace, name string) string {
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name);
 | 
			
		||||
	if node == nil { return "" }
 | 
			
		||||
	return node.Value;
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name)
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
	return node.Value
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get node value as int
 | 
			
		||||
func (this *Node) GetValuei(namespace, name string) int {
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name);
 | 
			
		||||
	if node == nil { return 0 }
 | 
			
		||||
	if node.Value == "" { return 0 }
 | 
			
		||||
	n, _ := strconv.Atoi(node.Value);
 | 
			
		||||
	return n;
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name)
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	if node.Value == "" {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	n, _ := strconv.Atoi(node.Value)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get node value as int64
 | 
			
		||||
func (this *Node) GetValuei64(namespace, name string) int64 {
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name);
 | 
			
		||||
	if node == nil { return 0 }
 | 
			
		||||
	if node.Value == "" { return 0 }
 | 
			
		||||
	n, _ := strconv.Atoi64(node.Value);
 | 
			
		||||
	return n;
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name)
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	if node.Value == "" {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	n, _ := strconv.Atoi64(node.Value)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get node value as uint
 | 
			
		||||
func (this *Node) GetValueui(namespace, name string) uint {
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name);
 | 
			
		||||
	if node == nil { return 0 }
 | 
			
		||||
	if node.Value == "" { return 0 }
 | 
			
		||||
	n, _ := strconv.Atoui(node.Value);
 | 
			
		||||
	return n;
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name)
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	if node.Value == "" {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	n, _ := strconv.Atoui(node.Value)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get node value as uint64
 | 
			
		||||
func (this *Node) GetValueui64(namespace, name string) uint64 {
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name);
 | 
			
		||||
	if node == nil { return 0 }
 | 
			
		||||
	if node.Value == "" { return 0 }
 | 
			
		||||
	n, _ := strconv.Atoui64(node.Value);
 | 
			
		||||
	return n;
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name)
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	if node.Value == "" {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	n, _ := strconv.Atoui64(node.Value)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get node value as float
 | 
			
		||||
func (this *Node) GetValuef(namespace, name string) float {
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name);
 | 
			
		||||
	if node == nil { return 0 }
 | 
			
		||||
	if node.Value == "" { return 0 }
 | 
			
		||||
	n, _ := strconv.Atof(node.Value);
 | 
			
		||||
	return n;
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name)
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	if node.Value == "" {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	n, _ := strconv.Atof(node.Value)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get node value as float32
 | 
			
		||||
func (this *Node) GetValuef32(namespace, name string) float32 {
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name);
 | 
			
		||||
	if node == nil { return 0 }
 | 
			
		||||
	if node.Value == "" { return 0 }
 | 
			
		||||
	n, _ := strconv.Atof32(node.Value);
 | 
			
		||||
	return n;
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name)
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	if node.Value == "" {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	n, _ := strconv.Atof32(node.Value)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get node value as float64
 | 
			
		||||
func (this *Node) GetValuef64(namespace, name string) float64 {
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name);
 | 
			
		||||
	if node == nil { return 0 }
 | 
			
		||||
	if node.Value == "" { return 0 }
 | 
			
		||||
	n, _ := strconv.Atof64(node.Value);
 | 
			
		||||
	return n;
 | 
			
		||||
	node := rec_SelectNode(this, namespace, name)
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	if node.Value == "" {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	n, _ := strconv.Atof64(node.Value)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get attribute value as string
 | 
			
		||||
func (this *Node) GetAttr(namespace, name string) string {
 | 
			
		||||
	for _, v := range this.Attributes {
 | 
			
		||||
		if namespace == v.Name.Space && name == v.Name.Local {
 | 
			
		||||
			return v.Value;
 | 
			
		||||
			return v.Value
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return "";
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get attribute value as int
 | 
			
		||||
func (this *Node) GetAttri(namespace, name string) int {
 | 
			
		||||
	s := this.GetAttr(namespace, name);
 | 
			
		||||
	if s == "" { return 0 }
 | 
			
		||||
	n, _ := strconv.Atoi(s);
 | 
			
		||||
	return n;
 | 
			
		||||
	s := this.GetAttr(namespace, name)
 | 
			
		||||
	if s == "" {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	n, _ := strconv.Atoi(s)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get attribute value as uint
 | 
			
		||||
func (this *Node) GetAttrui(namespace, name string) uint {
 | 
			
		||||
	s := this.GetAttr(namespace, name);
 | 
			
		||||
	if s == "" { return 0 }
 | 
			
		||||
	n, _ := strconv.Atoui(s);
 | 
			
		||||
	return n;
 | 
			
		||||
	s := this.GetAttr(namespace, name)
 | 
			
		||||
	if s == "" {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	n, _ := strconv.Atoui(s)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get attribute value as uint64
 | 
			
		||||
func (this *Node) GetAttrui64(namespace, name string) uint64 {
 | 
			
		||||
	s := this.GetAttr(namespace, name);
 | 
			
		||||
	if s == "" { return 0 }
 | 
			
		||||
	n, _ := strconv.Atoui64(s);
 | 
			
		||||
	return n;
 | 
			
		||||
	s := this.GetAttr(namespace, name)
 | 
			
		||||
	if s == "" {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	n, _ := strconv.Atoui64(s)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get attribute value as int64
 | 
			
		||||
func (this *Node) GetAttri64(namespace, name string) int64 {
 | 
			
		||||
	s := this.GetAttr(namespace, name);
 | 
			
		||||
	if s == "" { return 0 }
 | 
			
		||||
	n, _ := strconv.Atoi64(s);
 | 
			
		||||
	return n;
 | 
			
		||||
	s := this.GetAttr(namespace, name)
 | 
			
		||||
	if s == "" {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	n, _ := strconv.Atoi64(s)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get attribute value as float
 | 
			
		||||
func (this *Node) GetAttrf(namespace, name string) float {
 | 
			
		||||
	s := this.GetAttr(namespace, name);
 | 
			
		||||
	if s == "" { return 0 }
 | 
			
		||||
	n, _ := strconv.Atof(s);
 | 
			
		||||
	return n;
 | 
			
		||||
	s := this.GetAttr(namespace, name)
 | 
			
		||||
	if s == "" {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	n, _ := strconv.Atof(s)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get attribute value as float32
 | 
			
		||||
func (this *Node) GetAttrf32(namespace, name string) float32 {
 | 
			
		||||
	s := this.GetAttr(namespace, name);
 | 
			
		||||
	if s == "" { return 0 }
 | 
			
		||||
	n, _ := strconv.Atof32(s);
 | 
			
		||||
	return n;
 | 
			
		||||
	s := this.GetAttr(namespace, name)
 | 
			
		||||
	if s == "" {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	n, _ := strconv.Atof32(s)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get attribute value as float64
 | 
			
		||||
func (this *Node) GetAttrf64(namespace, name string) float64 {
 | 
			
		||||
	s := this.GetAttr(namespace, name);
 | 
			
		||||
	if s == "" { return 0 }
 | 
			
		||||
	n, _ := strconv.Atof64(s);
 | 
			
		||||
	return n;
 | 
			
		||||
	s := this.GetAttr(namespace, name)
 | 
			
		||||
	if s == "" {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	n, _ := strconv.Atof64(s)
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns true if this node has the specified attribute. False otherwise.
 | 
			
		||||
| 
						 | 
				
			
			@ -185,41 +229,41 @@ func (this *Node) HasAttr(namespace, name string) bool {
 | 
			
		|||
 | 
			
		||||
// Select single node by name
 | 
			
		||||
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 {
 | 
			
		||||
	if cn.Name.Space == namespace && cn.Name.Local == name {
 | 
			
		||||
		return cn;
 | 
			
		||||
		return cn
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, v := range cn.Children {
 | 
			
		||||
		tn := rec_SelectNode(v, namespace, name);
 | 
			
		||||
		if tn != nil { return tn }
 | 
			
		||||
		tn := rec_SelectNode(v, namespace, name)
 | 
			
		||||
		if tn != nil {
 | 
			
		||||
			return tn
 | 
			
		||||
		}
 | 
			
		||||
	return nil;
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Select multiple nodes by name
 | 
			
		||||
func (this *Node) SelectNodes(namespace, name string) []*Node {
 | 
			
		||||
	list := make([]*Node, 0);
 | 
			
		||||
	rec_SelectNodes(this, namespace, name, &list);
 | 
			
		||||
	return list;
 | 
			
		||||
	list := make([]*Node, 0)
 | 
			
		||||
	rec_SelectNodes(this, namespace, name, &list)
 | 
			
		||||
	return list
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func rec_SelectNodes(cn *Node, namespace, name string, list *[]*Node) {
 | 
			
		||||
	if cn.Name.Space == namespace && cn.Name.Local == name {
 | 
			
		||||
		slice := make([]*Node, len(*list) + 1);
 | 
			
		||||
		for i,v := range *list {
 | 
			
		||||
			slice[i] = v;
 | 
			
		||||
		}
 | 
			
		||||
		slice[len(slice) - 1] = cn;
 | 
			
		||||
		*list = slice;
 | 
			
		||||
		c := make([]*Node, len(*list)+1)
 | 
			
		||||
		copy(c, *list)
 | 
			
		||||
		c[len(c)-1] = cn
 | 
			
		||||
		*list = c
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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:
 | 
			
		||||
		s = this.printRoot()
 | 
			
		||||
	}
 | 
			
		||||
	return;
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Node) printRoot() (s string) {
 | 
			
		||||
	for _, v := range this.Children {
 | 
			
		||||
		s += v.String()
 | 
			
		||||
	}
 | 
			
		||||
	return;
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Node) printProcInst() (s string) {
 | 
			
		||||
	s = "<?" + this.Target + " " + this.Value + "?>";
 | 
			
		||||
	return;
 | 
			
		||||
	s = "<?" + this.Target + " " + this.Value + "?>"
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Node) printComment() (s string) {
 | 
			
		||||
	s = "<!-- " + this.Value + " -->";
 | 
			
		||||
	return;
 | 
			
		||||
	s = "<!-- " + this.Value + " -->"
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Node) printDirective() (s string) {
 | 
			
		||||
	s = "<!" + this.Value + "!>";
 | 
			
		||||
	return;
 | 
			
		||||
	s = "<!" + this.Value + "!>"
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 {
 | 
			
		||||
		s += " />";
 | 
			
		||||
		return;
 | 
			
		||||
		s += " />"
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s += ">";
 | 
			
		||||
	s += ">"
 | 
			
		||||
 | 
			
		||||
	for _, v := range this.Children {
 | 
			
		||||
		s += v.String()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s += this.Value;
 | 
			
		||||
	s += this.Value
 | 
			
		||||
	if len(this.Name.Space) > 0 {
 | 
			
		||||
		s += "</" + this.Name.Space + ":" + this.Name.Local + ">"
 | 
			
		||||
	} else {
 | 
			
		||||
		s += "</" + this.Name.Local + ">"
 | 
			
		||||
	}
 | 
			
		||||
	return;
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add a child node
 | 
			
		||||
| 
						 | 
				
			
			@ -305,38 +349,32 @@ func (this *Node) AddChild(t *Node) {
 | 
			
		|||
	if t.Parent != nil {
 | 
			
		||||
		t.Parent.RemoveChild(t)
 | 
			
		||||
	}
 | 
			
		||||
	t.Parent = this;
 | 
			
		||||
	t.Parent = this
 | 
			
		||||
 | 
			
		||||
	slice := make([]*Node, len(this.Children)+1);
 | 
			
		||||
	for i, v := range this.Children {
 | 
			
		||||
		slice[i] = v
 | 
			
		||||
	}
 | 
			
		||||
	slice[len(slice)-1] = t;
 | 
			
		||||
	this.Children = slice;
 | 
			
		||||
	c := make([]*Node, len(this.Children)+1)
 | 
			
		||||
	copy(c, this.Children)
 | 
			
		||||
	c[len(c)-1] = t
 | 
			
		||||
	this.Children = c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Remove a child node
 | 
			
		||||
func (this *Node) RemoveChild(t *Node) {
 | 
			
		||||
	pos := -1;
 | 
			
		||||
	p := -1
 | 
			
		||||
	for i, v := range this.Children {
 | 
			
		||||
		if v == t {
 | 
			
		||||
			pos = i;
 | 
			
		||||
			break;
 | 
			
		||||
			p = i
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if pos == -1 {
 | 
			
		||||
	if p == -1 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	slice := make([]*Node, len(this.Children)-1);
 | 
			
		||||
 | 
			
		||||
	idx := 0;
 | 
			
		||||
	for i, v := range this.Children {
 | 
			
		||||
		if i != pos {
 | 
			
		||||
			slice[idx] = v;
 | 
			
		||||
			idx++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	c := make([]*Node, len(this.Children)-1)
 | 
			
		||||
	copy(c, this.Children[0:p])
 | 
			
		||||
	copy(c[p:], this.Children[p+1:])
 | 
			
		||||
	this.Children = c
 | 
			
		||||
 | 
			
		||||
	t.Parent = nil;
 | 
			
		||||
	t.Parent = nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,108 +3,106 @@ package xmlx
 | 
			
		|||
import "testing"
 | 
			
		||||
 | 
			
		||||
func TestLoadLocal(t *testing.T) {
 | 
			
		||||
	doc := New();
 | 
			
		||||
	err := doc.LoadFile("test.xml");
 | 
			
		||||
	doc := New()
 | 
			
		||||
	err := doc.LoadFile("test.xml")
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("%s", err);
 | 
			
		||||
		return;
 | 
			
		||||
		t.Errorf("%s", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(doc.Root.Children) == 0 {
 | 
			
		||||
		t.Errorf("Root node has no children.");
 | 
			
		||||
		return;
 | 
			
		||||
		t.Errorf("Root node has no children.")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestLoadRemote(t *testing.T) {
 | 
			
		||||
	doc := New();
 | 
			
		||||
	err := doc.LoadUri("http://tldp.org/authors/template/Sample-HOWTO.xml");
 | 
			
		||||
	doc := New()
 | 
			
		||||
	err := doc.LoadUri("http://tldp.org/authors/template/Sample-HOWTO.xml")
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("%s", err);
 | 
			
		||||
		return;
 | 
			
		||||
		t.Errorf("%s", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(doc.Root.Children) == 0 {
 | 
			
		||||
		t.Errorf("Root node has no children.");
 | 
			
		||||
		return;
 | 
			
		||||
		t.Errorf("Root node has no children.")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestSave(t *testing.T) {
 | 
			
		||||
	doc := New();
 | 
			
		||||
	err := doc.LoadFile("test.xml");
 | 
			
		||||
	doc := New()
 | 
			
		||||
	err := doc.LoadFile("test.xml")
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("LoadFile(): %s", err);
 | 
			
		||||
		return;
 | 
			
		||||
		t.Errorf("LoadFile(): %s", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = doc.SaveFile("test1.xml");
 | 
			
		||||
	err = doc.SaveFile("test1.xml")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("SaveFile(): %s", err);
 | 
			
		||||
		return;
 | 
			
		||||
		t.Errorf("SaveFile(): %s", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestNodeSearch(t *testing.T) {
 | 
			
		||||
	doc := New();
 | 
			
		||||
	err := doc.LoadFile("test.xml");
 | 
			
		||||
	doc := New()
 | 
			
		||||
	err := doc.LoadFile("test.xml")
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("LoadFile(): %s", err);
 | 
			
		||||
		return;
 | 
			
		||||
		t.Errorf("LoadFile(): %s", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	node := doc.SelectNode("", "item");
 | 
			
		||||
	node := doc.SelectNode("", "item")
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		t.Errorf("SelectNode(): No node found.");
 | 
			
		||||
		return;
 | 
			
		||||
		t.Errorf("SelectNode(): No node found.")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	nodes := doc.SelectNodes("", "item");
 | 
			
		||||
	nodes := doc.SelectNodes("", "item")
 | 
			
		||||
	if len(nodes) == 0 {
 | 
			
		||||
		t.Errorf("SelectNodes(): no nodes found.");
 | 
			
		||||
		return;
 | 
			
		||||
		t.Errorf("SelectNodes(): no nodes found.")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Image struct {
 | 
			
		||||
	Title		string;
 | 
			
		||||
	Url		string;
 | 
			
		||||
	Link		string;
 | 
			
		||||
	Width		string;
 | 
			
		||||
	Height		string;
 | 
			
		||||
	Description	string;
 | 
			
		||||
	Title       string
 | 
			
		||||
	Url         string
 | 
			
		||||
	Link        string
 | 
			
		||||
	Width       string
 | 
			
		||||
	Height      string
 | 
			
		||||
	Description string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestUnmarshal(t *testing.T) {
 | 
			
		||||
	doc := New();
 | 
			
		||||
	err := doc.LoadFile("test.xml");
 | 
			
		||||
	doc := New()
 | 
			
		||||
	err := doc.LoadFile("test.xml")
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("LoadFile(): %s", err);
 | 
			
		||||
		return;
 | 
			
		||||
		t.Errorf("LoadFile(): %s", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	node := doc.SelectNode("", "image");
 | 
			
		||||
	node := doc.SelectNode("", "image")
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		t.Errorf("SelectNode(): No node found.");
 | 
			
		||||
		return;
 | 
			
		||||
		t.Errorf("SelectNode(): No node found.")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	img := Image{};
 | 
			
		||||
	err = node.Unmarshal(&img);
 | 
			
		||||
	img := Image{}
 | 
			
		||||
	err = node.Unmarshal(&img)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("Unmarshal(): %s", err);
 | 
			
		||||
		return;
 | 
			
		||||
		t.Errorf("Unmarshal(): %s", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if img.Title != "WriteTheWeb" {
 | 
			
		||||
		t.Errorf("Image.Title has incorrect value. Got '%s', expected 'WriteTheWeb'.", img.Title);
 | 
			
		||||
		return;
 | 
			
		||||
		t.Errorf("Image.Title has incorrect value. Got '%s', expected 'WriteTheWeb'.", img.Title)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue