func getChildElements(commands *commandsxml.CommandsXML, enc *xml.Encoder, children []byte, lang string) { if len(children) == 0 { enc.EncodeToken(emptyElement.Copy()) enc.EncodeToken(emptyElement.End()) } buf := bytes.NewBuffer(children) dec := xml.NewDecoder(buf) for { tok, err := dec.Token() if err != nil { return } switch v := tok.(type) { case xml.StartElement: switch v.Name.Local { case "cmd": ref := refElement.Copy() for _, attr := range v.Attr { if attr.Name.Local == "name" { ref.Attr = []xml.Attr{{Name: xml.Name{Local: "name"}, Value: "e_" + attr.Value}} } } enc.EncodeToken(ref) case "description": case "choice": enc.EncodeToken(choiceElement.Copy()) for _, attribute := range v.Attr { if attribute.Name.Local == lang { enc.EncodeToken(valueElement.Copy()) enc.EncodeToken(xml.CharData(attribute.Value)) enc.EncodeToken(valueElement.End()) } } case "reference": for _, attr := range v.Attr { if attr.Name.Local == "name" { getChildElements(commands, enc, commands.GetDefine(attr.Value), lang) } } default: enc.EncodeToken(v.Copy()) } case xml.EndElement: switch v.Name.Local { case "cmd": enc.EncodeToken(refElement.End()) case "choice": enc.EncodeToken(choiceElement.End()) default: enc.EncodeToken(v) } } } }
func genSchema(commands *commandsxml.CommandsXML, lang string) ([]byte, error) { var outbuf bytes.Buffer enc := xml.NewEncoder(&outbuf) enc.Indent("", " ") namespace := fmt.Sprintf("urn:speedata.de:2009/publisher/%s", lang) grammar := xml.StartElement{Name: xml.Name{Local: "grammar", Space: RELAXNG}} grammar.Attr = []xml.Attr{ {Name: xml.Name{Local: "xmlns:a"}, Value: "http://relaxng.org/ns/compatibility/annotations/1.0"}, {Name: xml.Name{Local: "xmlns:sch"}, Value: "http://purl.oclc.org/dsdl/schematron"}, {Name: xml.Name{Local: "ns"}, Value: namespace}, {Name: xml.Name{Local: "datatypeLibrary"}, Value: "http://www.w3.org/2001/XMLSchema-datatypes"}, } enc.EncodeToken(xml.Comment("Do not edit this file. Auto generated from commands.xml with sphelper.")) enc.EncodeToken(xml.CharData("\n")) enc.EncodeToken(grammar) sch := xml.StartElement{Name: xml.Name{Local: "sch:ns"}} sch.Attr = []xml.Attr{ {Name: xml.Name{Local: "prefix"}, Value: "t"}, {Name: xml.Name{Local: "uri"}, Value: namespace}, } enc.EncodeToken(sch) enc.EncodeToken(sch.End()) start := xml.StartElement{Name: xml.Name{Local: "start"}} enc.EncodeToken(start) choice := xml.StartElement{Name: xml.Name{Local: "choice"}} enc.EncodeToken(choice) refLayout := xml.StartElement{Name: xml.Name{Local: "ref"}} refLayout.Attr = []xml.Attr{{Name: xml.Name{Local: "name"}, Value: "e_Layout"}} refInclude := xml.StartElement{Name: xml.Name{Local: "ref"}} refInclude.Attr = []xml.Attr{{Name: xml.Name{Local: "name"}, Value: "e_Include"}} enc.EncodeToken(refLayout) enc.EncodeToken(refLayout.End()) enc.EncodeToken(refInclude) enc.EncodeToken(refInclude.End()) enc.EncodeToken(choice.End()) enc.EncodeToken(start.End()) attributeElement := xml.StartElement{Name: xml.Name{Local: "attribute"}} for _, cmd := range commands.Commands { enc.Flush() for _, r := range cmd.Rules { if r.Lang == lang { outbuf.WriteString(r.Rules) } } def := xml.StartElement{Name: xml.Name{Local: "define"}} def.Attr = []xml.Attr{{Name: xml.Name{Local: "name"}, Value: "e_" + cmd.En}} enc.EncodeToken(def) elt := xml.StartElement{Name: xml.Name{Local: "element"}} elt.Attr = []xml.Attr{{Name: xml.Name{Local: "name"}, Value: commands.TranslateCommand("en", lang, cmd.En)}} enc.EncodeToken(elt) doc := xml.StartElement{Name: xml.Name{Local: "a:documentation"}} enc.EncodeToken(doc) enc.EncodeToken(xml.CharData(cmd.GetCommandDescription(lang))) enc.EncodeToken(doc.End()) for _, attr := range cmd.Attributes { if attr.Optional == "yes" { enc.EncodeToken(optionalElement.Copy()) } attname, _ := commands.TranslateAttribute("en", lang, cmd.En, attr.En, "-") attelt := attributeElement.Copy() attelt.Attr = []xml.Attr{{Name: xml.Name{Local: "name"}, Value: attname}} enc.EncodeToken(attelt) doc := xml.StartElement{Name: xml.Name{Local: "a:documentation"}} enc.EncodeToken(doc) enc.EncodeToken(xml.CharData(attr.GetDescription(lang))) enc.EncodeToken(doc.End()) if len(attr.Choice) > 0 { enc.EncodeToken(choiceElement.Copy()) for _, choice := range attr.Choice { enc.EncodeToken(valueElement.Copy()) enc.EncodeToken(xml.CharData(choice.GetValue(lang))) enc.EncodeToken(valueElement.End()) doc := xml.StartElement{Name: xml.Name{Local: "a:documentation"}} enc.EncodeToken(doc) enc.EncodeToken(xml.CharData(choice.GetDescription(lang))) enc.EncodeToken(doc.End()) } if attr.AllowXPath == "yes" { data := xml.StartElement{Name: xml.Name{Local: "data"}} data.Attr = []xml.Attr{{Name: xml.Name{Local: "type"}, Value: "string"}} enc.EncodeToken(data) param := xml.StartElement{Name: xml.Name{Local: "param"}} param.Attr = []xml.Attr{{Name: xml.Name{Local: "name"}, Value: "pattern"}} enc.EncodeToken(param) enc.EncodeToken(xml.CharData(`\{.+\}`)) enc.EncodeToken(param.End()) enc.EncodeToken(data.End()) } enc.EncodeToken(choiceElement.End()) } if attr.Reference.Name != "" { d := commands.DefineAttrs for _, attrdefinition := range d { if attr.Reference.Name == attrdefinition.Name { enc.EncodeToken(choiceElement.Copy()) for _, choice := range attrdefinition.Choices { enc.EncodeToken(valueElement.Copy()) enc.EncodeToken(xml.CharData(choice.GetValue(lang))) enc.EncodeToken(valueElement.End()) doc := xml.StartElement{Name: xml.Name{Local: "a:documentation"}} enc.EncodeToken(doc) enc.EncodeToken(xml.CharData(choice.GetDescription(lang))) enc.EncodeToken(doc.End()) } enc.EncodeToken(choiceElement.End()) } } // attrsec := commands.GetDefineAttributes(attr.Reference.Name) // b := bytes.NewBuffer(attrsec) // d := xml.NewDecoder(b) // d.DecodeElement(cmd, start) } enc.EncodeToken(attelt.End()) if attr.Optional == "yes" { enc.EncodeToken(optionalElement.Copy().End()) } } getChildElements(commands, enc, cmd.Childelements.Text, lang) enc.EncodeToken(elt.End()) enc.EncodeToken(def.End()) } enc.EncodeToken(grammar.End()) enc.EncodeToken(xml.CharData("\n")) enc.Flush() return outbuf.Bytes(), nil }