Skip to content

Commit 0eea251

Browse files
pgundlachodeke-em
authored andcommitted
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>
1 parent 234283d commit 0eea251

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

api/next/45628.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pkg encoding/xml, method (*Decoder) InputPos() (int, int) #45628

src/encoding/xml/xml.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ type Decoder struct {
216216
ns map[string]string
217217
err error
218218
line int
219+
linestart int64
219220
offset int64
220221
unmarshalDepth int
221222
}
@@ -919,6 +920,7 @@ func (d *Decoder) getc() (b byte, ok bool) {
919920
}
920921
if b == '\n' {
921922
d.line++
923+
d.linestart = d.offset + 1
922924
}
923925
d.offset++
924926
return b, true
@@ -931,6 +933,13 @@ func (d *Decoder) InputOffset() int64 {
931933
return d.offset
932934
}
933935

936+
// InputPos retuns the line of the current decoder position and the 1 based
937+
// input position of the line. The position gives the location of the end of the
938+
// most recently returned token.
939+
func (d *Decoder) InputPos() (line, column int) {
940+
return d.line, int(d.offset-d.linestart) + 1
941+
}
942+
934943
// Return saved offset.
935944
// If we did ungetc (nextByte >= 0), have to back up one.
936945
func (d *Decoder) savedOffset() int {

src/encoding/xml/xml_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,45 @@ func TestSyntax(t *testing.T) {
502502
}
503503
}
504504

505+
func TestInputLinePos(t *testing.T) {
506+
testInput := `<root>
507+
<?pi
508+
?> <elt
509+
att
510+
=
511+
"val">
512+
<![CDATA[
513+
]]><!--
514+
515+
--></elt>
516+
</root>`
517+
linePos := [][]int{
518+
{1, 7},
519+
{2, 1},
520+
{3, 4},
521+
{3, 6},
522+
{6, 7},
523+
{7, 1},
524+
{8, 4},
525+
{10, 4},
526+
{10, 10},
527+
{11, 1},
528+
{11, 8},
529+
}
530+
dec := NewDecoder(strings.NewReader(testInput))
531+
for _, want := range linePos {
532+
if _, err := dec.Token(); err != nil {
533+
t.Errorf("Unexpected error: %v", err)
534+
continue
535+
}
536+
537+
gotLine, gotCol := dec.InputPos()
538+
if gotLine != want[0] || gotCol != want[1] {
539+
t.Errorf("dec.InputPos() = %d,%d, want %d,%d", gotLine, gotCol, want[0], want[1])
540+
}
541+
}
542+
}
543+
505544
type allScalars struct {
506545
True1 bool
507546
True2 bool

0 commit comments

Comments
 (0)