dorfylegends/analyze/df/structure.go
Robert Janetzko 757b7c6b79 bugfix fields
2022-04-14 17:06:52 +00:00

161 lines
2.8 KiB
Go

package df
import (
"encoding/json"
"encoding/xml"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/iancoleman/strcase"
"github.com/robertjanetzko/LegendsBrowser2/backend/util"
)
func AnalyzeStructure(filex string) error {
fmt.Println("Search...", filex)
files, err := filepath.Glob(filex + "/*.xml")
if err != nil {
return err
}
fmt.Println(files)
a := NewAnalyzeData()
for _, file := range files {
analyze(file, a)
}
return a.Save()
}
type FieldData struct {
IsString bool
Multiple bool
Base bool
Plus bool
}
func NewFieldData() *FieldData {
return &FieldData{}
}
type AnalyzeData struct {
Fields map[string]*FieldData
}
func NewAnalyzeData() *AnalyzeData {
return &AnalyzeData{
Fields: make(map[string]*FieldData, 0),
}
}
func (a *AnalyzeData) Save() error {
file, err := json.MarshalIndent(a, "", " ")
if err != nil {
return err
}
return ioutil.WriteFile("analyze.json", file, 0644)
}
func LoadAnalyzeData() (*AnalyzeData, error) {
data, err := ioutil.ReadFile("analyze.json")
if err != nil {
return nil, err
}
a := NewAnalyzeData()
json.Unmarshal(data, a)
return a, nil
}
func (a *AnalyzeData) GetField(s string) *FieldData {
if f, ok := a.Fields[s]; ok {
return f
} else {
f := &FieldData{}
a.Fields[s] = f
return f
}
}
func analyze(file string, a *AnalyzeData) error {
xmlFile, err := os.Open(file)
if err != nil {
fmt.Println(err)
}
plus := strings.HasSuffix(file, "_plus.xml")
fmt.Println("Successfully Opened", file)
defer xmlFile.Close()
converter := util.NewConvertReader(xmlFile)
return analyzeElement(xml.NewDecoder(converter), a, make([]string, 0), plus)
}
const PATH_SEPARATOR = "|"
func analyzeElement(d *xml.Decoder, a *AnalyzeData, path []string, plus bool) error {
if len(path) > 1 {
s := strings.Join(path, PATH_SEPARATOR)
fd := a.GetField(s)
if plus {
fd.Plus = true
} else {
fd.Base = true
}
}
var (
data []byte
)
value := true
fields := make(map[string]bool)
Loop:
for {
tok, err := d.Token()
if err == io.EOF {
break Loop
} else if err != nil {
return err
}
switch t := tok.(type) {
case xml.StartElement:
value = false
newPath := append(path, t.Name.Local)
if _, ok := fields[t.Name.Local]; ok {
a.GetField(strings.Join(newPath, PATH_SEPARATOR)).Multiple = true
}
fields[t.Name.Local] = true
analyzeElement(d, a, newPath, plus)
case xml.CharData:
data = append(data, t...)
case xml.EndElement:
if value {
if _, err := strconv.Atoi(string(data)); err != nil {
a.GetField(strings.Join(path, PATH_SEPARATOR)).IsString = true
}
}
if t.Name.Local == "type" {
path[len(path)-2] = path[len(path)-2] + "+" + strcase.ToCamel(string(data))
}
return nil
}
}
return nil
}