diff options
| author | Patrick Gundlach <gundlach@speedata.de> | 2021-04-19 12:51:04 +0200 |
|---|---|---|
| committer | Emmanuel Odeke <emmanuel@orijtech.com> | 2022-03-27 20:26:46 +0000 |
| commit | 0eea25159fe58ab956198f3009e6ded875d2796e (patch) | |
| tree | 5a99bfc092797894d302ae70997eed52e1dc18a7 /src/encoding/xml | |
| parent | 234283d8aba1e892906e889782ae5723686da6c6 (diff) | |
| download | go-0eea25159fe58ab956198f3009e6ded875d2796e.tar.xz | |
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>
Diffstat (limited to 'src/encoding/xml')
| -rw-r--r-- | src/encoding/xml/xml.go | 9 | ||||
| -rw-r--r-- | src/encoding/xml/xml_test.go | 39 |
2 files changed, 48 insertions, 0 deletions
diff --git a/src/encoding/xml/xml.go b/src/encoding/xml/xml.go index ef51252dcb..a7a02f5b57 100644 --- a/src/encoding/xml/xml.go +++ b/src/encoding/xml/xml.go @@ -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 { diff --git a/src/encoding/xml/xml_test.go b/src/encoding/xml/xml_test.go index ab1dbf849b..8f0d97b6a6 100644 --- a/src/encoding/xml/xml_test.go +++ b/src/encoding/xml/xml_test.go @@ -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 |
