()
| 165 | } |
| 166 | |
| 167 | func (p *parser) parse() (*Node, error) { |
| 168 | p.once.Do(func() { |
| 169 | p.space2prefix = map[string]*xmlnsPrefix{"http://www.w3.org/XML/1998/namespace": {name: "xml", level: 0}} |
| 170 | }) |
| 171 | |
| 172 | var streamElementNodeCounter int |
| 173 | for { |
| 174 | p.reader.StartCaching() |
| 175 | tok, err := p.decoder.Token() |
| 176 | p.reader.StopCaching() |
| 177 | |
| 178 | // Update line number based on processed content |
| 179 | p.updateLineNumber() |
| 180 | |
| 181 | if err != nil { |
| 182 | return nil, err |
| 183 | } |
| 184 | |
| 185 | switch tok := tok.(type) { |
| 186 | case xml.StartElement: |
| 187 | if p.level == 0 { |
| 188 | // mising XML declaration |
| 189 | attributes := make([]Attr, 1) |
| 190 | attributes[0].Name = xml.Name{Local: "version"} |
| 191 | attributes[0].Value = "1.0" |
| 192 | node := &Node{ |
| 193 | Type: DeclarationNode, |
| 194 | Data: "xml", |
| 195 | Attr: attributes, |
| 196 | level: 1, |
| 197 | LineNumber: p.currentLine, |
| 198 | } |
| 199 | AddChild(p.prev, node) |
| 200 | p.level = 1 |
| 201 | p.prev = node |
| 202 | } |
| 203 | |
| 204 | for _, att := range tok.Attr { |
| 205 | if att.Name.Local == "xmlns" { |
| 206 | // https://github.com/antchfx/xmlquery/issues/67 |
| 207 | if prefix, ok := p.space2prefix[att.Value]; !ok || (ok && prefix.level >= p.level) { |
| 208 | p.space2prefix[att.Value] = &xmlnsPrefix{name: "", level: p.level} // reset empty if exist the default namespace |
| 209 | } |
| 210 | } else if att.Name.Space == "xmlns" { |
| 211 | // maybe there are have duplicate NamespaceURL? |
| 212 | p.space2prefix[att.Value] = &xmlnsPrefix{name: att.Name.Local, level: p.level} |
| 213 | } |
| 214 | } |
| 215 | |
| 216 | if space := tok.Name.Space; space != "" { |
| 217 | if _, found := p.space2prefix[space]; !found && p.decoder.Strict { |
| 218 | return nil, fmt.Errorf("xmlquery: invalid XML document, namespace %s is missing", space) |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | attributes := make([]Attr, len(tok.Attr)) |
| 223 | for i, att := range tok.Attr { |
| 224 | name := att.Name |
no test coverage detected