| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- package etreeutils
- import "github.com/beevik/etree"
- // SortedAttrs provides sorting capabilities, compatible with XML C14N, on top
- // of an []etree.Attr
- type SortedAttrs []etree.Attr
- func (a SortedAttrs) Len() int {
- return len(a)
- }
- func (a SortedAttrs) Swap(i, j int) {
- a[i], a[j] = a[j], a[i]
- }
- func (a SortedAttrs) Less(i, j int) bool {
- // This is the best reference I've found on sort order:
- // http://dst.lbl.gov/~ksb/Scratch/XMLC14N.html
- // If attr j is a default namespace declaration, attr i may
- // not be strictly "less" than it.
- if a[j].Space == defaultPrefix && a[j].Key == xmlnsPrefix {
- return false
- }
- // Otherwise, if attr i is a default namespace declaration, it
- // must be less than anything else.
- if a[i].Space == defaultPrefix && a[i].Key == xmlnsPrefix {
- return true
- }
- // Next, namespace prefix declarations, sorted by prefix, come before
- // anythign else.
- if a[i].Space == xmlnsPrefix {
- if a[j].Space == xmlnsPrefix {
- return a[i].Key < a[j].Key
- }
- return true
- }
- if a[j].Space == xmlnsPrefix {
- return false
- }
- // Then come unprefixed attributes, sorted by key.
- if a[i].Space == defaultPrefix {
- if a[j].Space == defaultPrefix {
- return a[i].Key < a[j].Key
- }
- return true
- }
- if a[j].Space == defaultPrefix {
- return false
- }
- // Wow. We're still going. Finally, attributes in the same namespace should be
- // sorted by key. Attributes in different namespaces should be sorted by the
- // actual namespace (_not_ the prefix). For now just use the prefix.
- if a[i].Space == a[j].Space {
- return a[i].Key < a[j].Key
- }
- return a[i].Space < a[j].Space
- }
|