diff --git a/README.md b/README.md index afe66f3..41848bc 100644 --- a/README.md +++ b/README.md @@ -14,13 +14,20 @@ Manuals are available on godoc.org [![GoDoc](https://godoc.org/github.com/webabi TO DO: ====== -XML to Application decoder -Application to XML and JSON encoders -Tests +- Adds local specific functions to all the Containers, Elements, Zones, etc to improve tree programmation. +- Tests Version Changes Control ======================= +v0.0.5 - 2020-03-07 +----------------------- +- Added UnmarshalXML +- Added MarshalJSON +- Added basic functions AddMessage, AddHelp, AddEvent to a Node, with auto creation of children nodes +- Removed messages, events, help attributes of Node +- Added AddZone() to SeparatorContainer as a new struct extended from DomDef interface to build upon specific functions for specific nodes (it works) + v0.0.4 - 2020-03-06 ----------------------- - All structures and Application tree implemented in GO diff --git a/accordioncontainer.go b/accordioncontainer.go index b7e5b99..322cba4 100644 --- a/accordioncontainer.go +++ b/accordioncontainer.go @@ -8,7 +8,7 @@ func NewAccordionContainer(id string) AccordionContainer { c.SetID(id) c.RegisterKnownAttributes([]string{"display", "style", "classname", "classnamezone", "left", "width", "right", "top", "height", "bottom", "haslistener"}) - c.RegisterKnownChildren([]string{"zone"}) + c.RegisterKnownChildren([]string{"zone", "event", "help", "message"}) return c } diff --git a/application.go b/application.go new file mode 100644 index 0000000..28aeed9 --- /dev/null +++ b/application.go @@ -0,0 +1,14 @@ +package wajaf + +type Application NodeDef + +func NewApplication(id string) Application { + + app := NewNode("application", "") + app.SetID(id) + + app.RegisterKnownAttributes([]string{"id", "enforce", "style"}) + app.RegisterKnownChildren([]string{"container", "element"}) + + return app +} diff --git a/buttonelement.go b/buttonelement.go index 3afb5e6..0c02748 100644 --- a/buttonelement.go +++ b/buttonelement.go @@ -9,7 +9,7 @@ func NewButtonElement(id string) ButtonElement { e.RegisterKnownAttributes([]string{"display", "style", "classname", "left", "width", "right", "top", "height", "bottom", "visible", "action", "status", "extra"}) - e.RegisterKnownMessages([]string{"titleinsert", "titleupdate", "titledelete", "titleview"}) + // e.RegisterKnownMessages([]string{"titleinsert", "titleupdate", "titledelete", "titleview"}) return e } diff --git a/event.go b/event.go new file mode 100644 index 0000000..506f768 --- /dev/null +++ b/event.go @@ -0,0 +1,11 @@ +package wajaf + +type Event NodeDef + +func NewEvent(name string, value string) Event { + + e := NewNode("event", name) + e.SetData(value) + + return e +} diff --git a/groupcontainer.go b/groupcontainer.go index c4c2677..29d97e2 100644 --- a/groupcontainer.go +++ b/groupcontainer.go @@ -9,7 +9,7 @@ func NewGroupContainer(id string) GroupContainer { c.RegisterKnownAttributes([]string{"display", "style", "classname", "classnamezone", "left", "width", "right", "top", "height", "bottom", "haslistener", "mode", "authmodes", "varkey", "key", "varorder", "varmode"}) - c.RegisterKnownMessages([]string{"alertmessage", "servermessage", "titleinsert", "titleupdate", "titledelete", "titleview", "insertok", "updateok", "deleteok"}) + // c.RegisterKnownMessages([]string{"alertmessage", "servermessage", "titleinsert", "titleupdate", "titledelete", "titleview", "insertok", "updateok", "deleteok"}) c.RegisterKnownChildren([]string{"zone", "dataset"}) return c diff --git a/help.go b/help.go new file mode 100644 index 0000000..e6415a2 --- /dev/null +++ b/help.go @@ -0,0 +1,13 @@ +package wajaf + +type Help NodeDef + +func NewHelp(tooltip string, title string, description string) Help { + + e := NewNode("help", "") + e.AddMessage("summary", tooltip) + e.AddMessage("title", title) + e.AddMessage("description", description) + + return e +} diff --git a/htmlelement.go b/htmlelement.go index b3358d5..6c4627c 100644 --- a/htmlelement.go +++ b/htmlelement.go @@ -1,10 +1,10 @@ package wajaf -type HTMLFieldElement NodeDef +type HTMLElement NodeDef -func NewHTMLFieldElement(id string, data string) HTMLFieldElement { +func NewHTMLElement(id string, data string) HTMLElement { - e := NewNode("element", "htlmelement") + e := NewNode("element", "htmlelement") e.SetID(id) e.SetData(data) diff --git a/lovfieldelement.go b/lovfieldelement.go index 0c8b1b2..2f26305 100644 --- a/lovfieldelement.go +++ b/lovfieldelement.go @@ -10,7 +10,7 @@ func NewLOVFieldElement(id string, data string) LOVFieldElement { e.RegisterKnownAttributes([]string{"display", "style", "classname", "left", "width", "right", "top", "height", "bottom", "size", "visible", "info", "disabled", "readonly", "notnull", "helpmode"}) - e.RegisterKnownMessages([]string{"defaultvalue", "helpdescription", "statusnotnull", "statuscheck"}) + // e.RegisterKnownMessages([]string{"defaultvalue", "helpdescription", "statusnotnull", "statuscheck"}) return e } diff --git a/message.go b/message.go new file mode 100644 index 0000000..17b9b1d --- /dev/null +++ b/message.go @@ -0,0 +1,11 @@ +package wajaf + +type Message NodeDef + +func NewMessage(name string, value string) Message { + + e := NewNode(name, "") + e.SetData(value) + + return e +} diff --git a/node.go b/node.go index e76de76..ea71b49 100644 --- a/node.go +++ b/node.go @@ -1,6 +1,9 @@ package wajaf import ( + "bytes" + "encoding/json" + "encoding/xml" "errors" "fmt" "strings" @@ -11,54 +14,43 @@ type NodeDef interface { fmt.GoStringer RegisterKnownAttributes([]string) error - RegisterKnownMessages([]string) error RegisterKnownChildren([]string) error + SetID(id string) SetData(data string) + GetID() string + GetType() string GetSuperType() string + GetData() string SetAttribute(string, string) error SetAttributes(Attributes) error GetAttribute(string) (string, error) GetAttributes() Attributes - SetMessage(string, string) error - SetMessages(Messages) error - GetMessage(string) (string, error) - GetMessages() Messages - SetEvent(string, string) - SetEvents(Events) - GetEvent(string) string - GetEvents() Events + AddHelp(string, string, string) + AddMessage(string, string) + AddEvent(string, string) AddChild(NodeDef) error GetChildren() []NodeDef - SetHelp(string, string, string) - GetHelp() (string, string, string) // DecodeAttributes(xml.StartElement) - // UnmarshalXML(*xml.Decoder, xml.StartElement) error - // MarshalXML(*xml.Encoder) error - // UnmarshalJSON([]byte) error - // MarshalJSON() ([]byte, error) + UnmarshalXML(*xml.Decoder, xml.StartElement) error + MarshalXML(*xml.Encoder) error + UnmarshalJSON([]byte) error + MarshalJSON() ([]byte, error) } type Attributes map[string]string -type Messages map[string]string -type Events map[string]string type Node struct { knownAttributes map[string]bool knownChildren map[string]bool - knownMessages map[string]bool - ID string - SuperType string - Type string - Data string - attributes Attributes - messages Messages - events Events - children []NodeDef - helptooltip string - helptitle string - helpdescription string + + ID string + SuperType string + Type string + Data string + attributes Attributes + children []NodeDef } func NewNode(supertype string, subtype string) NodeDef { @@ -81,13 +73,6 @@ func (n *Node) RegisterKnownAttributes(attributes []string) error { return nil } -func (n *Node) RegisterKnownMessages(messages []string) error { - for _, v := range messages { - n.knownMessages[v] = true - } - return nil -} - func (n *Node) RegisterKnownChildren(children []string) error { for _, v := range children { n.knownChildren[v] = true @@ -103,10 +88,22 @@ func (n *Node) SetData(data string) { n.Data = data } +func (n *Node) GetID() string { + return n.ID +} + func (n *Node) GetSuperType() string { return n.SuperType } +func (n *Node) GetType() string { + return n.Type +} + +func (n *Node) GetData() string { + return n.Data +} + var errUnknownAttribute = errors.New("Node: unknown attribute for this type of node") func (n *Node) SetAttribute(name string, value string) error { @@ -138,53 +135,19 @@ func (n *Node) GetAttributes() Attributes { return n.attributes } -var errUnknownMessage = errors.New("Node: unknown message for this type of node") - -func (n *Node) SetMessage(name string, value string) error { - if !n.knownMessages[name] { - return errUnknownMessage - } - n.messages[name] = value - return nil -} - -func (n *Node) SetMessages(mesg Messages) error { - for name, value := range mesg { - if !n.knownMessages[name] { - return errUnknownMessage - } - n.messages[name] = value - } - return nil +func (n *Node) AddHelp(tooltip string, title string, description string) { + h := NewHelp(tooltip, title, description) + n.children = append(n.children, h) } -func (n *Node) GetMessage(name string) (string, error) { - if !n.knownMessages[name] { - return "", errUnknownMessage - } - return n.messages[name], nil +func (n *Node) AddMessage(name string, value string) { + m := NewMessage(name, value) + n.children = append(n.children, m) } -func (n *Node) GetMessages() Messages { - return n.messages -} - -func (n *Node) SetEvent(name string, value string) { - n.events[name] = value -} - -func (n *Node) SetEvents(evts Events) { - for name, value := range evts { - n.events[name] = value - } -} - -func (n *Node) GetEvent(name string) string { - return n.events[name] -} - -func (n *Node) GetEvents() Events { - return n.events +func (n *Node) AddEvent(name string, code string) { + e := NewEvent(name, code) + n.children = append(n.children, e) } var errUnknownChildren = errors.New("Node: unknown children for this type of node") @@ -215,7 +178,7 @@ func (n *Node) String() string { } func (n *Node) GoString() string { - sdata := []string{n.SuperType + ":" + n.Type} + sdata := []string{n.SuperType + ":" + n.Type + ":" + n.ID + ":(" + fmt.Sprint(len(n.Data)) + ")"} for key, val := range n.attributes { sdata = append(sdata, key+":"+val) } @@ -225,258 +188,113 @@ func (n *Node) GoString() string { return "#{" + strings.Join(sdata, " ") + "}" } -func (n *Node) SetHelp(tooltip string, title string, description string) { - n.helptooltip = tooltip - n.helptitle = title - n.helpdescription = description -} - -func (n *Node) GetHelp() (string, string, string) { - return n.helptooltip, n.helptitle, n.helpdescription -} - -/* -type Container struct { - Node - Zones []*Zone `xml:"zone"` - Events []*Event `xml:"event"` -} - -func (c *Container) DecodeAttributes(s xml.StartElement) { - for _, v := range s.Attr { - if v.Name.Local == "id" { - c.ID = v.Value - } - if v.Name.Local == "type" { - c.Type = v.Value - } - } -} - -func (c *Container) String() string { - sdata := []string{"id:" + c.ID + " " + "Type:" + c.Type} - for _, val := range c.Zones { - sdata = append(sdata, "#"+fmt.Sprintf("%v", val)) - } - for _, val := range c.Events { - sdata = append(sdata, "@"+fmt.Sprintf("%v", val)) - } - return "CNT{" + strings.Join(sdata, "\n") + "}" -} - -// GoString will transform the XDataset into a readable string for humans -func (c *Container) GoString() string { - return c.String() -} - -type Zone struct { - Node - Containers []*Container `xml:"container"` - Elements []*Element `xml:"element"` - Events []*Event `xml:"event"` -} - -func (z *Zone) DecodeAttributes(s xml.StartElement) { - for _, v := range s.Attr { - if v.Name.Local == "id" { - z.ID = v.Value - } - if v.Name.Local == "type" { - z.Type = v.Value - } - } -} - -func (z *Zone) String() string { - sdata := []string{"id:" + z.ID} - for _, val := range z.Containers { - sdata = append(sdata, "+"+fmt.Sprintf("%v", val)) - } - for _, val := range z.Elements { - sdata = append(sdata, "."+fmt.Sprintf("%v", val)) - } - for _, val := range z.Events { - sdata = append(sdata, "@"+fmt.Sprintf("%v", val)) - } - return "ZON{" + strings.Join(sdata, "\n") + "}" -} - -// GoString will transform the XDataset into a readable string for humans -func (z *Zone) GoString() string { - return z.String() -} - -type Element struct { - Node - Events []*Event `xml:"event"` -} - -func (e *Element) DecodeAttributes(s xml.StartElement) { +func (n *Node) DecodeAttributes(s xml.StartElement) { for _, v := range s.Attr { if v.Name.Local == "id" { - e.ID = v.Value + n.ID = v.Value + continue } if v.Name.Local == "type" { - e.Type = v.Value + n.Type = v.Value + continue } + n.attributes[v.Name.Local] = v.Value } } -type Event struct { - Node -} - -func (e *Event) DecodeAttributes(s xml.StartElement) { - for _, v := range s.Attr { - if v.Name.Local == "type" { - e.Type = v.Value - } - } -} +func (n *Node) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { -func (a *App) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - - a.DecodeAttributes(start) + n.DecodeAttributes(start) for { t, _ := d.Token() switch tt := t.(type) { case xml.StartElement: etype := tt.Name.Local - switch etype { - case "container": - c := &Container{} - c.UnmarshalXML(d, tt) - a.Containers = append(a.Containers, c) - case "element": - e := &Element{} - e.UnmarshalXML(d, tt) - a.Elements = append(a.Elements, e) - case "event": - e := &Event{} - e.UnmarshalXML(d, tt) - a.Events = append(a.Events, e) - default: - } + z := NewNode(etype, "") + z.UnmarshalXML(d, tt) + n.children = append(n.children, z) case xml.EndElement: if tt.Name == start.Name { return nil } case xml.CharData: - // fmt.Println("APP*", string(tt)) + n.Data = string(tt) } } + return nil } -func (c *Container) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - - c.DecodeAttributes(start) - - for { - t, _ := d.Token() - switch tt := t.(type) { - case xml.StartElement: - etype := tt.Name.Local - switch etype { - case "zone": - z := &Zone{} - z.UnmarshalXML(d, tt) - c.Zones = append(c.Zones, z) - case "event": - e := &Event{} - e.UnmarshalXML(d, tt) - c.Events = append(c.Events, e) - default: - } +func (n *Node) MarshalXML(*xml.Encoder) error { + return nil +} - case xml.EndElement: - if tt.Name == start.Name { - return nil - } - case xml.CharData: - // fmt.Println("CONTAINER*", string(tt)) - } - } +func (n *Node) UnmarshalJSON([]byte) error { + return nil } -func (e *Element) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { +func (n *Node) MarshalJSON() ([]byte, error) { - e.DecodeAttributes(start) + buffer := bytes.NewBufferString("{\"tag\":\"" + n.SuperType + "\"") - for { - t, _ := d.Token() - switch tt := t.(type) { - case xml.StartElement: - etype := tt.Name.Local - switch etype { - case "event": - ne := &Event{} - ne.UnmarshalXML(d, tt) - e.Events = append(e.Events, ne) - default: - // Error, an element cannot have other elements into + // Attributes: + length := len(n.attributes) + candidate := length != 0 || n.ID != "" || n.Type != "" + if candidate { + buffer.WriteString(",\"attributes\":{") + if n.ID != "" { + buffer.WriteString("\"id\":\"" + n.ID + "\"") + } + if n.Type != "" { + if n.ID != "" { + buffer.WriteString(",") } - - case xml.EndElement: - if tt.Name == start.Name { - return nil + buffer.WriteString("\"type\":\"" + n.Type + "\"") + } + count := 0 + for akey, avalue := range n.attributes { + if count > 0 || n.ID != "" || n.Type != "" { + buffer.WriteString(",") } - case xml.CharData: - // fmt.Println("ELEMENT*", string(tt)) + jsonValue, err := json.Marshal(avalue) + if err != nil { + return nil, err + } + buffer.WriteString(fmt.Sprintf("\"%s\":%s", akey, string(jsonValue))) + count++ } + buffer.WriteString("}") } -} - -func (z *Zone) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - z.DecodeAttributes(start) - - for { - t, _ := d.Token() - switch tt := t.(type) { - case xml.StartElement: - etype := tt.Name.Local - switch etype { - case "container": - c := &Container{} - c.UnmarshalXML(d, tt) - z.Containers = append(z.Containers, c) - case "element": - e := &Element{} - e.UnmarshalXML(d, tt) - z.Elements = append(z.Elements, e) - case "event": - e := &Event{} - e.UnmarshalXML(d, tt) - z.Events = append(z.Events, e) - default: + // children + clength := len(n.children) + if clength > 0 { + buffer.WriteString(",\"children\":[") + count := 0 + for _, cvalue := range n.children { + if count > 0 { + buffer.WriteString(",") } - - case xml.EndElement: - if tt.Name == start.Name { - return nil + jsonValue, err := json.Marshal(cvalue) + if err != nil { + return nil, err } - case xml.CharData: - // fmt.Println("ZONE*", string(tt)) + buffer.WriteString(fmt.Sprintf("%s", string(jsonValue))) + count++ } + buffer.WriteString("]") } -} - -func (e *Event) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - e.DecodeAttributes(start) - - for { - t, _ := d.Token() - switch tt := t.(type) { - case xml.EndElement: - if tt.Name == start.Name { - return nil - } - case xml.CharData: - // fmt.Println("EVENT*", string(tt)) + // data + if n.Data != "" { + jsonValue, err := json.Marshal(n.Data) + if err != nil { + return nil, err } + buffer.WriteString(",\"data\":" + string(jsonValue)) } + + buffer.WriteString("}") + return buffer.Bytes(), nil } -*/ diff --git a/separatorcontainer.go b/separatorcontainer.go index 44b16de..f65a9ff 100644 --- a/separatorcontainer.go +++ b/separatorcontainer.go @@ -1,10 +1,17 @@ package wajaf -type SeparatorContainer NodeDef +// type SeparatorContainer NodeDef -func NewSeparatorContainer(id string) SeparatorContainer { +type SeparatorContainer struct { + NodeDef +} + +func NewSeparatorContainer(id string) *SeparatorContainer { - c := NewNode("container", "separatorcontainer") + c := &SeparatorContainer{ + NodeDef: NewNode("container", "separatorcontainer"), + } + // c := NewNode("container", "separatorcontainer") c.SetID(id) c.RegisterKnownAttributes([]string{"display", "style", "classname", "classnamezone", "left", "width", "right", "top", "height", "bottom", "haslistener", @@ -14,6 +21,12 @@ func NewSeparatorContainer(id string) SeparatorContainer { return c } +func (c *SeparatorContainer) NewZone(id string) NodeDef { + z := NewSeparatorZone(id) + c.AddChild(z) + return z +} + type SeparatorZone NodeDef func NewSeparatorZone(id string) SeparatorZone { diff --git a/textareafieldelement.go b/textareafieldelement.go index 2b07d75..ad62700 100644 --- a/textareafieldelement.go +++ b/textareafieldelement.go @@ -10,7 +10,7 @@ func NewTextAreaFieldElement(id string, data string) TextAreaFieldElement { e.RegisterKnownAttributes([]string{"display", "style", "classname", "left", "width", "right", "top", "height", "bottom", "areawidth", "areaheight", "minlength", "maxlength", "minwords", "maxwords", "format", "visible", "info", "disabled", "readonly", "notnull", "helpmode"}) - e.RegisterKnownMessages([]string{"defaultvalue", "helpdescription", "statusnotnull", "statusbadformat", "statustooshort", "statustoolong", "statustoofewwords", "statustoomanywords", "statuscheck"}) + // e.RegisterKnownMessages([]string{"defaultvalue", "helpdescription", "statusnotnull", "statusbadformat", "statustooshort", "statustoolong", "statustoofewwords", "statustoomanywords", "statuscheck"}) return e } diff --git a/textfieldelement.go b/textfieldelement.go index b9d73d8..587a5a3 100644 --- a/textfieldelement.go +++ b/textfieldelement.go @@ -10,7 +10,7 @@ func NewTextFieldElement(id string, data string) TextFieldElement { e.RegisterKnownAttributes([]string{"display", "style", "classname", "left", "width", "right", "top", "height", "bottom", "size", "minlength", "maxlength", "minwords", "maxwords", "format", "visible", "info", "disabled", "readonly", "notnull", "helpmode"}) - e.RegisterKnownMessages([]string{"defaultvalue", "helpdescription", "statusnotnull", "statusbadformat", "statustooshort", "statustoolong", "statustoofewwords", "statustoomanywords", "statuscheck"}) + // e.RegisterKnownMessages([]string{"defaultvalue", "helpdescription", "statusnotnull", "statusbadformat", "statustooshort", "statustoolong", "statustoofewwords", "statustoomanywords", "statuscheck"}) return e } diff --git a/wajaf.go b/wajaf.go index 5a86752..60bcb86 100644 --- a/wajaf.go +++ b/wajaf.go @@ -7,56 +7,9 @@ package wajaf // VERSION is the used version nombre of the XCore library. -const VERSION = "0.0.4" +const VERSION = "0.0.5" // LOG is the flag to activate logging on the library. // if LOG is set to TRUE, LOG indicates to the XCore libraries to log a trace of functions called, with most important parameters. // LOG can be set to true or false dynamically to trace only parts of code on demand. var LOG = false - -type Application NodeDef - -func NewApplication(id string) Application { - - app := NewNode("application", "") - app.SetID(id) - - app.RegisterKnownAttributes([]string{"id", "enforce", "style"}) - app.RegisterKnownChildren([]string{"container", "element", "event"}) - - return app -} - -/* -func (a *Application) DecodeAttributes(s xml.StartElement) { - for _, v := range s.Attr { - if v.Name.Local == "id" { - a.ID = v.Value - } - } -} - -func (a *App) String() string { - sdata := []string{"id:" + a.ID} - for _, val := range a.Containers { - sdata = append(sdata, "+"+fmt.Sprintf("%v", val)) - } - for _, val := range a.Elements { - sdata = append(sdata, "."+fmt.Sprintf("%v", val)) - } - for _, val := range a.Events { - sdata = append(sdata, "@"+fmt.Sprintf("%v", val)) - } - return "APP{" + strings.Join(sdata, "\n") + "}" -} - -// GoString will transform the XDataset into a readable string for humans -func (a *App) GoString() string { - return a.String() -} - -func (a *App) MarshalJSON() ([]byte, error) { - - return []byte("{\"status\":\"OK\"}"), nil -} -*/ diff --git a/wajaf_test.go b/wajaf_test.go index 7dbe4f8..9571717 100644 --- a/wajaf_test.go +++ b/wajaf_test.go @@ -1,18 +1,20 @@ package wajaf import ( + "encoding/json" + "encoding/xml" "fmt" "io/ioutil" "testing" ) -func readfile(name string, t *testing.T) string { - str, err := ioutil.ReadFile(name) +func readfile(name string, t *testing.T) []byte { + data, err := ioutil.ReadFile(name) if err != nil { t.Errorf("Error loading XML File errors into string %s", err) - return "" + return nil } - return string(str) + return data } func TestWajaf(t *testing.T) { @@ -22,18 +24,41 @@ func TestWajaf(t *testing.T) { c1.SetAttributes(Attributes{"width": "max", "height": "max", "mode": "vertical", "auto": "yes"}) app.AddChild(c1) - fmt.Printf("APP = %#v\n", app) + z0 := c1.NewZone("z0") + z0.AddChild(NewHTMLElement("", "HTML

ELEMENT

CONTENT")) + + z1 := NewSeparatorZone("z1") + z1.AddHelp("tooltip on z1", "z1 help", "You can use z1 clicking on it") + z1.AddMessage("messageid", "The message is any string with specific tag name") + + c1.AddChild(z1) + + z2 := NewSeparatorZone("z2") + c1.AddChild(z2) + + e1 := NewCodeElement("code1") + app.AddChild(e1) + + app.AddEvent("start", "function() { alert('Wajaf working'); }") + + data, err := json.Marshal(app) + fmt.Printf("JSON = %s, %v\n", string(data), err) return - /* - data := readfile("testunit/app.code", t) +} + +func TestWajafLoad(t *testing.T) { + + app := NewApplication("manual_application") + + data := readfile("testunit/app.code", t) + xml.Unmarshal(data, app) - w := NewAppFromXMLString(data) + // fmt.Printf("XML TO APP: %#v\n", app) - fmt.Printf("%#v\n", w) + s, err := json.Marshal(app) - s, err := json.Marshal(w) + fmt.Println("JSON = ", string(s), err) - fmt.Println("JSON = ", string(s), err) - */ + return }