in lib/xml/xml.go [61:138]
func Details(doc []byte) (map[string]Detail, error) {
schema, err := xsd.Parse(doc)
if err != nil {
return nil, err
}
tree := make(map[string]string)
leaves := make(map[string]Detail)
for _, s := range schema {
for n, t := range s.Types {
switch t := t.(type) {
case xsd.Builtin:
case *xsd.SimpleType:
case *xsd.ComplexType:
// Ignore external name-spaced names.
if t.Name.Space != "" {
continue
}
// Ignore anonymous node and the root.
if strings.HasPrefix(n.Local, "_") {
continue
}
for _, e := range t.Elements {
var d Detail
tree[e.Name.Local] = n.Local
switch builtinTypeFor(e.Type) {
case xsd.Boolean:
d.Type = BoolType
case xsd.Int, xsd.Integer, xsd.Long, xsd.NonNegativeInteger,
xsd.NonPositiveInteger, xsd.PositiveInteger, xsd.Short,
xsd.UnsignedByte, xsd.UnsignedInt, xsd.UnsignedLong, xsd.UnsignedShort:
d.Type = IntType
case xsd.Decimal, xsd.Double, xsd.Float:
d.Type = FloatType
}
d.Plural = e.Plural
if d.isZero() {
continue
}
leaves[e.Name.Local] = d
}
default:
panic(fmt.Sprintf("unknown type: %T", t))
}
}
}
details := Detail{Children: make(map[string]Detail)}
var path []string
for p, d := range leaves {
path = append(path[:0], p)
for i := 0; i <= len(tree); i++ {
parent, ok := tree[p]
if !ok {
break
}
path = append(path, parent)
p = parent
}
reverse(path)
n := details
for i, e := range path {
c := n.Children[e]
if c.Children == nil && i < len(path)-1 {
c.Children = make(map[string]Detail)
}
if i == len(path)-1 {
c.Type = d.Type
c.Plural = d.Plural
}
n.Children[e] = c
n = c
}
}
return details.Children, nil
}