Skip to content

Commit

Permalink
Move stuff around
Browse files Browse the repository at this point in the history
  • Loading branch information
tkrajina committed Mar 9, 2021
1 parent 357507d commit ed695a5
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 196 deletions.
3 changes: 0 additions & 3 deletions gpx/converters.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,12 +322,9 @@ func NewGPXAttributes(attrs []xml.Attr) GPXAttributes {
namespacesByUrls[attr.Value] = attr.Name.Local
}
}
fmt.Printf("namespaces: %#v\n", namespacesByUrls)

res := map[string]map[string]Attr{}
for _, attr := range attrs {
// fmt.Println("space=", attr.Name.Space)
// fmt.Println("local=", attr.Name.Local)
space := attr.Name.Space
if ns, found := namespacesByUrls[attr.Name.Space]; found {
space = ns
Expand Down
192 changes: 0 additions & 192 deletions gpx/gpx11.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,200 +7,8 @@ package gpx

import (
"encoding/xml"
"strings"
)

type Node struct {
XMLName xml.Name
Attrs []xml.Attr `xml:",any,attr"`
Data string `xml:",chardata"`
Nodes []Node `xml:",any"`
}

func (n Node) debugXMLChunk() []byte {
byts, err := xml.MarshalIndent(n, "", " ")
if err != nil {
return []byte("???")
}
return byts
}

func (n Node) toTokens(prefix string) (tokens []xml.Token) {
var attrs []xml.Attr
for _, a := range n.Attrs {
attrs = append(attrs, xml.Attr{Name: xml.Name{Local: prefix + a.Name.Local}, Value: a.Value})
}

start := xml.StartElement{Name: xml.Name{Local: prefix + n.XMLName.Local, Space: ""}, Attr: attrs}
tokens = append(tokens, start)
data := strings.TrimSpace(n.Data)
if len(n.Nodes) > 0 {
for _, node := range n.Nodes {
tokens = append(tokens, node.toTokens(prefix)...)
}
} else if data != "" {
tokens = append(tokens, xml.CharData(data))
} else {
return nil
}
tokens = append(tokens, xml.EndElement{start.Name})
return
}

func (n *Node) GetAttr(key string) (value string, found bool) {
for i := range n.Attrs {
if n.Attrs[i].Name.Local == key {
value = n.Attrs[i].Value
found = true
return
}
}
return
}

func (n *Node) SetAttr(key, value string) {
for i := range n.Attrs {
if n.Attrs[i].Name.Local == key {
n.Attrs[i].Value = value
return
}
}
n.Attrs = append(n.Attrs, xml.Attr{
Name: xml.Name{
Space: n.SpaceNameURL(),
Local: key,
},
Value: value,
})
}

func (n *Node) GetNode(path0 string) (node *Node, found bool) {
for subn := range n.Nodes {
if n.Nodes[subn].LocalName() == path0 {
node = &n.Nodes[subn]
found = true
return
}
}
return
}

func (n *Node) getOrCreateNode(path ...string) *Node {
if len(path) == 0 {
return n
}

path0, rest := path[0], path[1:]

subNode, found := n.GetNode(path0)
if !found {
n.Nodes = append(n.Nodes, Node{
XMLName: xml.Name{
Space: n.XMLName.Space,
Local: path0,
},
Attrs: nil,
})
subNode = &(n.Nodes[len(n.Nodes)-1])
}

return subNode.getOrCreateNode(rest...)
}

func (n Node) IsEmpty() bool { return len(n.Nodes) == 0 && len(n.Attrs) == 0 && len(n.Data) == 0 }
func (n Node) LocalName() string { return n.XMLName.Local }
func (n Node) SpaceNameURL() string { return n.XMLName.Space }
func (n Node) GetAttrOrEmpty(attr string) string {
val, _ := n.GetAttr(attr)
return val
}

type Extension struct {
// XMLName xml.Name
// Attrs []xml.Attr `xml:",any,attr"`
Nodes []Node `xml:",any"`

// Filled before deserializing:
globalNsAttrs map[string]Attr
}

var _ xml.Marshaler = Extension{}

func (ex Extension) debugXMLChunk() []byte {
byts, err := xml.MarshalIndent(ex, "", " ")
if err != nil {
return []byte("???")
}
return byts
}

func (ex Extension) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
if len(ex.Nodes) == 0 {
return nil
}

start = xml.StartElement{Name: xml.Name{Local: start.Name.Local}, Attr: nil}
tokens := []xml.Token{start}
for _, node := range ex.Nodes {
prefix := ""
for _, v := range ex.globalNsAttrs {
if node.SpaceNameURL() == v.Value || node.SpaceNameURL() == v.Name.Local {
prefix = v.replacement
}
}
tokens = append(tokens, node.toTokens(prefix)...)
}

tokens = append(tokens, xml.EndElement{Name: start.Name})

for _, t := range tokens {
err := e.EncodeToken(t)
if err != nil {
return err
}
}

// flush to ensure tokens are written
err := e.Flush()
if err != nil {
return err
}

return nil
}

func (ex *Extension) GetOrCreateNode(namespaceURL string, path ...string) *Node {
// TODO: Check is len(nodes) == 0
var subNode *Node
for n := range ex.Nodes {
if ex.Nodes[n].SpaceNameURL() == namespaceURL && ex.Nodes[n].LocalName() == path[0] {
subNode = &ex.Nodes[n]
break
}
}
if subNode == nil {
ex.Nodes = append(ex.Nodes, Node{
XMLName: xml.Name{
Space: namespaceURL,
Local: path[0],
},
})
subNode = &ex.Nodes[len(ex.Nodes)-1]
}
return subNode.getOrCreateNode(path[1:]...)
}

func (ex *Extension) GetNode(path0 string) (node *Node, found bool) {
for subn := range ex.Nodes {
if ex.Nodes[subn].LocalName() == path0 {
node = &ex.Nodes[subn]
found = true
return
}
}
return
}

/*
The GPX XML hierarchy:
Expand Down
Loading

0 comments on commit ed695a5

Please sign in to comment.