Mercurial > gemma
changeset 372:15369b41be74
Teach WFS proxy about default namespaces.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Thu, 09 Aug 2018 17:59:28 +0200 |
parents | d5b707bbd1d5 |
children | 7e7e978d1cac |
files | controllers/externalwfs.go |
diffstat | 1 files changed, 79 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/controllers/externalwfs.go Thu Aug 09 17:21:12 2018 +0200 +++ b/controllers/externalwfs.go Thu Aug 09 17:59:28 2018 +0200 @@ -226,7 +226,7 @@ return strings.Replace(s, from, to, -1) } - var ns nsdef + var n nsdef tokens: for { @@ -240,46 +240,48 @@ switch t := tok.(type) { case xml.StartElement: - ns = ns.push() t = t.Copy() - attr := make([]xml.Attr, len(t.Attr)) + isDef := n.isDef(t.Name.Space) + n = n.push() - for i, at := range t.Attr { - at.Value = replace(at.Value) - switch { - case at.Name.Space == "xmlns": - ns.define(at.Value, at.Name.Local) - at.Name.Local = "xmlns:" + at.Name.Local - at.Name.Space = "" + for i := range t.Attr { + t.Attr[i].Value = replace(t.Attr[i].Value) + n.checkDef(&t.Attr[i]) + } - case at.Name.Space != "": - if s := ns.lookup(at.Name.Space); s != "" { - at.Name.Local = s + ":" + at.Name.Local - at.Name.Space = "" - } - } + for i := range t.Attr { + n.adjust(&t.Attr[i]) + } - attr[i] = at - } - if s := ns.lookup(t.Name.Space); s != "" { + switch { + case isDef: t.Name.Space = "" - t.Name.Local = s + ":" + t.Name.Local + default: + if s := n.lookup(t.Name.Space); s != "" { + t.Name.Space = "" + t.Name.Local = s + ":" + t.Name.Local + } } - t.Attr = attr tok = t case xml.CharData: tok = xml.CharData(replace(string(t))) case xml.EndElement: - if s := ns.lookup(t.Name.Space); s != "" { + s := n.lookup(t.Name.Space) + + n = n.pop() + + if n.isDef(t.Name.Space) { + t.Name.Space = "" + } else if s != "" { t.Name.Space = "" t.Name.Local = s + ":" + t.Name.Local - tok = t } - ns = ns.pop() + tok = t } + if err := encoder.EncodeToken(tok); err != nil { return err } @@ -288,31 +290,74 @@ return encoder.Flush() } -type nsdef []map[string]string +type nsframe struct { + def string + ns map[string]string +} + +type nsdef []nsframe + +func (n nsdef) setDef(def string) { + if l := len(n); l > 0 { + n[l-1].def = def + } +} + +func (n nsdef) isDef(s string) bool { + for i := len(n) - 1; i >= 0; i-- { + if x := n[i].def; x != "" { + return s == x + } + } + return false +} + +func (n nsdef) define(ns, s string) { + if l := len(n); l > 0 { + n[l-1].ns[ns] = s + } +} func (n nsdef) lookup(ns string) string { for i := len(n) - 1; i >= 0; i-- { - if s := n[i][ns]; s != "" { + if s := n[i].ns[ns]; s != "" { return s } } return "" } +func (n nsdef) checkDef(at *xml.Attr) { + if at.Name.Space == "" && at.Name.Local == "xmlns" { + n.setDef(at.Value) + } +} + +func (n nsdef) adjust(at *xml.Attr) { + switch { + case at.Name.Space == "xmlns": + n.define(at.Value, at.Name.Local) + at.Name.Local = "xmlns:" + at.Name.Local + at.Name.Space = "" + + case at.Name.Space != "": + if n.isDef(at.Name.Space) { + at.Name.Space = "" + } else if s := n.lookup(at.Name.Space); s != "" { + at.Name.Local = s + ":" + at.Name.Local + at.Name.Space = "" + } + } +} + func (n nsdef) push() nsdef { - return append(n, make(map[string]string)) + return append(n, nsframe{ns: make(map[string]string)}) } func (n nsdef) pop() nsdef { if l := len(n); l > 0 { - n[l-1] = nil + n[l-1] = nsframe{} n = n[:l-1] } return n } - -func (n nsdef) define(ns, s string) { - if n != nil { - n[len(n)-1][ns] = s - } -}