1
0
mirror of https://github.com/golang/go synced 2024-11-11 22:20:22 -07:00

encoding/xml: expose decoder line and column

The existing implementation of the xml decoder uses the line number
only for reporting syntax errors. The line number of the last read
token and the column within the line is useful for the users even
in non-error conditions.

Fixes #45628

Change-Id: I37b5033ff5ff8411793d8f5180f96aa4537e83f5
Reviewed-on: https://go-review.googlesource.com/c/go/+/311270
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Trust: Emmanuel Odeke <emmanuel@orijtech.com>
This commit is contained in:
Patrick Gundlach 2021-04-19 12:51:04 +02:00 committed by Emmanuel Odeke
parent 234283d8ab
commit 0eea25159f
3 changed files with 49 additions and 0 deletions

1
api/next/45628.txt Normal file
View File

@ -0,0 +1 @@
pkg encoding/xml, method (*Decoder) InputPos() (int, int) #45628

View File

@ -216,6 +216,7 @@ type Decoder struct {
ns map[string]string
err error
line int
linestart int64
offset int64
unmarshalDepth int
}
@ -919,6 +920,7 @@ func (d *Decoder) getc() (b byte, ok bool) {
}
if b == '\n' {
d.line++
d.linestart = d.offset + 1
}
d.offset++
return b, true
@ -931,6 +933,13 @@ func (d *Decoder) InputOffset() int64 {
return d.offset
}
// InputPos retuns the line of the current decoder position and the 1 based
// input position of the line. The position gives the location of the end of the
// most recently returned token.
func (d *Decoder) InputPos() (line, column int) {
return d.line, int(d.offset-d.linestart) + 1
}
// Return saved offset.
// If we did ungetc (nextByte >= 0), have to back up one.
func (d *Decoder) savedOffset() int {

View File

@ -502,6 +502,45 @@ func TestSyntax(t *testing.T) {
}
}
func TestInputLinePos(t *testing.T) {
testInput := `<root>
<?pi
?> <elt
att
=
"val">
<![CDATA[
]]><!--
--></elt>
</root>`
linePos := [][]int{
{1, 7},
{2, 1},
{3, 4},
{3, 6},
{6, 7},
{7, 1},
{8, 4},
{10, 4},
{10, 10},
{11, 1},
{11, 8},
}
dec := NewDecoder(strings.NewReader(testInput))
for _, want := range linePos {
if _, err := dec.Token(); err != nil {
t.Errorf("Unexpected error: %v", err)
continue
}
gotLine, gotCol := dec.InputPos()
if gotLine != want[0] || gotCol != want[1] {
t.Errorf("dec.InputPos() = %d,%d, want %d,%d", gotLine, gotCol, want[0], want[1])
}
}
}
type allScalars struct {
True1 bool
True2 bool