...

Source file src/github.com/clbanning/mxj/v2/misc.go

Documentation: github.com/clbanning/mxj/v2

     1  // Copyright 2016 Charles Banning. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file
     4  
     5  // misc.go - mimic functions (+others) called out in:
     6  //          https://groups.google.com/forum/#!topic/golang-nuts/jm_aGsJNbdQ
     7  // Primarily these methods let you retrive XML structure information.
     8  
     9  package mxj
    10  
    11  import (
    12  	"fmt"
    13  	"sort"
    14  	"strings"
    15  )
    16  
    17  // Return the root element of the Map. If there is not a single key in Map,
    18  // then an error is returned.
    19  func (mv Map) Root() (string, error) {
    20  	mm := map[string]interface{}(mv)
    21  	if len(mm) != 1 {
    22  		return "", fmt.Errorf("Map does not have singleton root. Len: %d.", len(mm))
    23  	}
    24  	for k, _ := range mm {
    25  		return k, nil
    26  	}
    27  	return "", nil
    28  }
    29  
    30  // If the path is an element with sub-elements, return a list of the sub-element
    31  // keys.  (The list is alphabeticly sorted.)  NOTE: Map keys that are prefixed with
    32  // '-', a hyphen, are considered attributes; see m.Attributes(path).
    33  func (mv Map) Elements(path string) ([]string, error) {
    34  	e, err := mv.ValueForPath(path)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	switch e.(type) {
    39  	case map[string]interface{}:
    40  		ee := e.(map[string]interface{})
    41  		elems := make([]string, len(ee))
    42  		var i int
    43  		for k, _ := range ee {
    44  			if len(attrPrefix) > 0 && strings.Index(k, attrPrefix) == 0 {
    45  				continue // skip attributes
    46  			}
    47  			elems[i] = k
    48  			i++
    49  		}
    50  		elems = elems[:i]
    51  		// alphabetic sort keeps things tidy
    52  		sort.Strings(elems)
    53  		return elems, nil
    54  	}
    55  	return nil, fmt.Errorf("no elements for path: %s", path)
    56  }
    57  
    58  // If the path is an element with attributes, return a list of the attribute
    59  // keys.  (The list is alphabeticly sorted.)  NOTE: Map keys that are not prefixed with
    60  // '-', a hyphen, are not treated as attributes; see m.Elements(path). Also, if the
    61  // attribute prefix is "" - SetAttrPrefix("") or PrependAttrWithHyphen(false) - then
    62  // there are no identifiable attributes.
    63  func (mv Map) Attributes(path string) ([]string, error) {
    64  	a, err := mv.ValueForPath(path)
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  	switch a.(type) {
    69  	case map[string]interface{}:
    70  		aa := a.(map[string]interface{})
    71  		attrs := make([]string, len(aa))
    72  		var i int
    73  		for k, _ := range aa {
    74  			if len(attrPrefix) == 0 || strings.Index(k, attrPrefix) != 0 {
    75  				continue // skip non-attributes
    76  			}
    77  			attrs[i] = k[len(attrPrefix):]
    78  			i++
    79  		}
    80  		attrs = attrs[:i]
    81  		// alphabetic sort keeps things tidy
    82  		sort.Strings(attrs)
    83  		return attrs, nil
    84  	}
    85  	return nil, fmt.Errorf("no attributes for path: %s", path)
    86  }
    87  

View as plain text