Got rid of depracated Node api functions. Removed dependency on go-iconv in favor of go-charset (See README). go-charset is a native Go package and thus requires no CGO functionality. Meaning go-pkg-xmlx and go-pkg-rss can now be used in Google AppEngine. Some speed and memory efficiency improvements added. Should now do a lot less []byte -> string conversions.
This commit is contained in:
parent
882ba8d0bb
commit
ea7fc45209
5 changed files with 128 additions and 244 deletions
178
node.go
178
node.go
|
@ -6,7 +6,6 @@ package xmlx
|
|||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"xml"
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
@ -22,18 +21,18 @@ const (
|
|||
)
|
||||
|
||||
type Attr struct {
|
||||
Name xml.Name
|
||||
Value string
|
||||
Name xml.Name // Attribute namespace and name.
|
||||
Value string // Attribute value.
|
||||
}
|
||||
|
||||
type Node struct {
|
||||
Type byte
|
||||
Name xml.Name
|
||||
Children []*Node
|
||||
Attributes []*Attr
|
||||
Parent *Node
|
||||
Value string
|
||||
Target string // procinst field
|
||||
Type byte // Node type.
|
||||
Name xml.Name // Node namespace and name.
|
||||
Children []*Node // Child nodes.
|
||||
Attributes []*Attr // Node attributes.
|
||||
Parent *Node // Parent node.
|
||||
Value string // Node value.
|
||||
Target string // procinst field.
|
||||
}
|
||||
|
||||
func NewNode(tid byte) *Node {
|
||||
|
@ -47,7 +46,7 @@ func NewNode(tid byte) *Node {
|
|||
// 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(bytes.NewBuffer(this.Bytes()), obj)
|
||||
}
|
||||
|
||||
// Get node value as string
|
||||
|
@ -58,10 +57,6 @@ func (this *Node) S(namespace, name string) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
// Deprecated - use Node.S()
|
||||
func (this *Node) GetValue(namespace, name string) string { return this.S(namespace, name) }
|
||||
|
||||
|
||||
// Get node value as int
|
||||
func (this *Node) I(namespace, name string) int {
|
||||
if node := rec_SelectNode(this, namespace, name); node != nil && node.Value != "" {
|
||||
|
@ -71,10 +66,6 @@ func (this *Node) I(namespace, name string) int {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Deprecated - use Node.I()
|
||||
func (this *Node) GetValuei(namespace, name string) int { return this.I(namespace, name) }
|
||||
|
||||
|
||||
// Get node value as int64
|
||||
func (this *Node) I64(namespace, name string) int64 {
|
||||
if node := rec_SelectNode(this, namespace, name); node != nil && node.Value != "" {
|
||||
|
@ -84,10 +75,6 @@ func (this *Node) I64(namespace, name string) int64 {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Deprecated - use Node.I64()
|
||||
func (this *Node) GetValuei64(namespace, name string) int64 { return this.I64(namespace, name) }
|
||||
|
||||
|
||||
// Get node value as uint
|
||||
func (this *Node) U(namespace, name string) uint {
|
||||
if node := rec_SelectNode(this, namespace, name); node != nil && node.Value != "" {
|
||||
|
@ -97,10 +84,6 @@ func (this *Node) U(namespace, name string) uint {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Deprecated - use Node.U()
|
||||
func (this *Node) GetValueui(namespace, name string) uint { return this.U(namespace, name) }
|
||||
|
||||
|
||||
// Get node value as uint64
|
||||
func (this *Node) U64(namespace, name string) uint64 {
|
||||
if node := rec_SelectNode(this, namespace, name); node != nil && node.Value != "" {
|
||||
|
@ -110,9 +93,6 @@ func (this *Node) U64(namespace, name string) uint64 {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Deprecated - use Node.U64()
|
||||
func (this *Node) GetValueui64(namespace, name string) uint64 { return this.U64(namespace, name) }
|
||||
|
||||
// Get node value as float32
|
||||
func (this *Node) F32(namespace, name string) float32 {
|
||||
if node := rec_SelectNode(this, namespace, name); node != nil && node.Value != "" {
|
||||
|
@ -122,10 +102,6 @@ func (this *Node) F32(namespace, name string) float32 {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Deprecated - use Node.F32()
|
||||
func (this *Node) GetValuef32(namespace, name string) float32 { return this.F32(namespace, name) }
|
||||
|
||||
|
||||
// Get node value as float64
|
||||
func (this *Node) F64(namespace, name string) float64 {
|
||||
if node := rec_SelectNode(this, namespace, name); node != nil && node.Value != "" {
|
||||
|
@ -135,10 +111,6 @@ func (this *Node) F64(namespace, name string) float64 {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Deprecated - use Node.F64()
|
||||
func (this *Node) GetValuef64(namespace, name string) float64 { return this.F64(namespace, name) }
|
||||
|
||||
|
||||
// Get node value as bool
|
||||
func (this *Node) B(namespace, name string) bool {
|
||||
if node := rec_SelectNode(this, namespace, name); node != nil && node.Value != "" {
|
||||
|
@ -158,10 +130,6 @@ func (this *Node) As(namespace, name string) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
// Deprecated - use Node.As()
|
||||
func (this *Node) GetAttr(namespace, name string) string { return this.As(namespace, name) }
|
||||
|
||||
|
||||
// Get attribute value as int
|
||||
func (this *Node) Ai(namespace, name string) int {
|
||||
if s := this.As(namespace, name); s != "" {
|
||||
|
@ -171,10 +139,6 @@ func (this *Node) Ai(namespace, name string) int {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Deprecated - use Node.Ai()
|
||||
func (this *Node) GetAttri(namespace, name string) int { return this.Ai(namespace, name) }
|
||||
|
||||
|
||||
// Get attribute value as uint
|
||||
func (this *Node) Au(namespace, name string) uint {
|
||||
if s := this.As(namespace, name); s != "" {
|
||||
|
@ -184,10 +148,6 @@ func (this *Node) Au(namespace, name string) uint {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Deprecated - use Node.Au()
|
||||
func (this *Node) GetAttrui(namespace, name string) uint { return this.Au(namespace, name) }
|
||||
|
||||
|
||||
// Get attribute value as uint64
|
||||
func (this *Node) Au64(namespace, name string) uint64 {
|
||||
if s := this.As(namespace, name); s != "" {
|
||||
|
@ -197,10 +157,6 @@ func (this *Node) Au64(namespace, name string) uint64 {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Deprecated - use Node.Au64()
|
||||
func (this *Node) GetAttrui64(namespace, name string) uint64 { return this.Au64(namespace, name) }
|
||||
|
||||
|
||||
// Get attribute value as int64
|
||||
func (this *Node) Ai64(namespace, name string) int64 {
|
||||
if s := this.As(namespace, name); s != "" {
|
||||
|
@ -210,9 +166,6 @@ func (this *Node) Ai64(namespace, name string) int64 {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Deprecated - use Node.Ai64()
|
||||
func (this *Node) GetAttri64(namespace, name string) int64 { return this.Ai64(namespace, name) }
|
||||
|
||||
// Get attribute value as float32
|
||||
func (this *Node) Af32(namespace, name string) float32 {
|
||||
if s := this.As(namespace, name); s != "" {
|
||||
|
@ -222,9 +175,6 @@ func (this *Node) Af32(namespace, name string) float32 {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Deprecated - use Node.Af32()
|
||||
func (this *Node) GetAttrf32(namespace, name string) float32 { return this.Af32(namespace, name) }
|
||||
|
||||
// Get attribute value as float64
|
||||
func (this *Node) Af64(namespace, name string) float64 {
|
||||
if s := this.As(namespace, name); s != "" {
|
||||
|
@ -234,10 +184,6 @@ func (this *Node) Af64(namespace, name string) float64 {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Deprecated - use Node.Af64()
|
||||
func (this *Node) GetAttrf64(namespace, name string) float64 { return this.Af64(namespace, name) }
|
||||
|
||||
|
||||
// Get attribute value as bool
|
||||
func (this *Node) Ab(namespace, name string) bool {
|
||||
if s := this.As(namespace, name); s != "" {
|
||||
|
@ -298,94 +244,100 @@ func rec_SelectNodes(cn *Node, namespace, name string, list *[]*Node) {
|
|||
}
|
||||
}
|
||||
|
||||
// Convert node to appropriate []byte representation based on it's @Type.
|
||||
// Note that NT_ROOT is a special-case empty node used as the root for a
|
||||
// Document. This one has no representation by itself. It merely forwards the
|
||||
// String() call to it's child nodes.
|
||||
func (this *Node) Bytes() (b []byte) {
|
||||
switch this.Type {
|
||||
case NT_PROCINST:
|
||||
b = this.printProcInst()
|
||||
case NT_COMMENT:
|
||||
b = this.printComment()
|
||||
case NT_DIRECTIVE:
|
||||
b = this.printDirective()
|
||||
case NT_ELEMENT:
|
||||
b = this.printElement()
|
||||
case NT_ROOT:
|
||||
b = this.printRoot()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Convert node to appropriate string representation based on it's @Type.
|
||||
// Note that NT_ROOT is a special-case empty node used as the root for a
|
||||
// Document. This one has no representation by itself. It merely forwards the
|
||||
// String() call to it's child nodes.
|
||||
func (this *Node) String() (s string) {
|
||||
switch this.Type {
|
||||
case NT_PROCINST:
|
||||
s = this.printProcInst()
|
||||
case NT_COMMENT:
|
||||
s = this.printComment()
|
||||
case NT_DIRECTIVE:
|
||||
s = this.printDirective()
|
||||
case NT_ELEMENT:
|
||||
s = this.printElement()
|
||||
case NT_ROOT:
|
||||
s = this.printRoot()
|
||||
}
|
||||
return
|
||||
return string(this.Bytes())
|
||||
}
|
||||
|
||||
func (this *Node) printRoot() (s string) {
|
||||
var data []byte
|
||||
buf := bytes.NewBuffer(data)
|
||||
func (this *Node) printRoot() []byte {
|
||||
var b bytes.Buffer
|
||||
for _, v := range this.Children {
|
||||
buf.WriteString(v.String())
|
||||
b.WriteString(v.String())
|
||||
}
|
||||
return buf.String()
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
func (this *Node) printProcInst() string {
|
||||
return "<?" + this.Target + " " + this.Value + "?>"
|
||||
func (this *Node) printProcInst() []byte {
|
||||
return []byte("<?" + this.Target + " " + this.Value + "?>")
|
||||
}
|
||||
|
||||
func (this *Node) printComment() string {
|
||||
return "<!-- " + this.Value + " -->"
|
||||
func (this *Node) printComment() []byte {
|
||||
return []byte("<!-- " + this.Value + " -->")
|
||||
}
|
||||
|
||||
func (this *Node) printDirective() string {
|
||||
return "<!" + this.Value + "!>"
|
||||
func (this *Node) printDirective() []byte {
|
||||
return []byte("<!" + this.Value + "!>")
|
||||
}
|
||||
|
||||
func (this *Node) printElement() string {
|
||||
var data []byte
|
||||
buf := bytes.NewBuffer(data)
|
||||
func (this *Node) printElement() []byte {
|
||||
var b bytes.Buffer
|
||||
|
||||
if len(this.Name.Space) > 0 {
|
||||
buf.WriteRune('<')
|
||||
buf.WriteString(this.Name.Space)
|
||||
buf.WriteRune(':')
|
||||
buf.WriteString(this.Name.Local)
|
||||
b.WriteRune('<')
|
||||
b.WriteString(this.Name.Space)
|
||||
b.WriteRune(':')
|
||||
b.WriteString(this.Name.Local)
|
||||
} else {
|
||||
buf.WriteRune('<')
|
||||
buf.WriteString(this.Name.Local)
|
||||
b.WriteRune('<')
|
||||
b.WriteString(this.Name.Local)
|
||||
}
|
||||
|
||||
for _, v := range this.Attributes {
|
||||
if len(v.Name.Space) > 0 {
|
||||
buf.WriteString(fmt.Sprintf(` %s:%s="%s"`, v.Name.Space, v.Name.Local, v.Value))
|
||||
b.WriteString(fmt.Sprintf(` %s:%s="%s"`, v.Name.Space, v.Name.Local, v.Value))
|
||||
} else {
|
||||
buf.WriteString(fmt.Sprintf(` %s="%s"`, v.Name.Local, v.Value))
|
||||
b.WriteString(fmt.Sprintf(` %s="%s"`, v.Name.Local, v.Value))
|
||||
}
|
||||
}
|
||||
|
||||
if len(this.Children) == 0 && len(this.Value) == 0 {
|
||||
buf.WriteString(" />")
|
||||
return buf.String()
|
||||
b.WriteString(" />")
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
buf.WriteRune('>')
|
||||
b.WriteRune('>')
|
||||
|
||||
for _, v := range this.Children {
|
||||
buf.WriteString(v.String())
|
||||
b.WriteString(v.String())
|
||||
}
|
||||
|
||||
buf.WriteString(this.Value)
|
||||
b.WriteString(this.Value)
|
||||
if len(this.Name.Space) > 0 {
|
||||
buf.WriteString("</")
|
||||
buf.WriteString(this.Name.Space)
|
||||
buf.WriteRune(':')
|
||||
buf.WriteString(this.Name.Local)
|
||||
buf.WriteRune('>')
|
||||
b.WriteString("</")
|
||||
b.WriteString(this.Name.Space)
|
||||
b.WriteRune(':')
|
||||
b.WriteString(this.Name.Local)
|
||||
b.WriteRune('>')
|
||||
} else {
|
||||
buf.WriteString("</")
|
||||
buf.WriteString(this.Name.Local)
|
||||
buf.WriteRune('>')
|
||||
b.WriteString("</")
|
||||
b.WriteString(this.Name.Local)
|
||||
b.WriteRune('>')
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
// Add a child node
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue