summaryrefslogtreecommitdiff
path: root/src/pkg/xml/xml.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/xml/xml.go')
-rw-r--r--src/pkg/xml/xml.go498
1 files changed, 249 insertions, 249 deletions
diff --git a/src/pkg/xml/xml.go b/src/pkg/xml/xml.go
index 360a39863..346b34649 100644
--- a/src/pkg/xml/xml.go
+++ b/src/pkg/xml/xml.go
@@ -15,20 +15,20 @@ package xml
// Expose parser line number in errors.
import (
- "bufio";
- "bytes";
- "io";
- "os";
- "strconv";
- "strings";
- "unicode";
- "utf8";
+ "bufio"
+ "bytes"
+ "io"
+ "os"
+ "strconv"
+ "strings"
+ "unicode"
+ "utf8"
)
// A SyntaxError represents a syntax error in the XML input stream.
type SyntaxError string
-func (e SyntaxError) String() string { return "XML syntax error: " + string(e) }
+func (e SyntaxError) String() string { return "XML syntax error: " + string(e) }
// A Name represents an XML name (Local) annotated
// with a name space identifier (Space).
@@ -36,13 +36,13 @@ func (e SyntaxError) String() string { return "XML syntax error: " + string(e) }
// is given as a canonical URL, not the short prefix used
// in the document being parsed.
type Name struct {
- Space, Local string;
+ Space, Local string
}
// An Attr represents an attribute in an XML element (Name=Value).
type Attr struct {
- Name Name;
- Value string;
+ Name Name
+ Value string
}
// A Token is an interface holding one of the token types:
@@ -51,13 +51,13 @@ type Token interface{}
// A StartElement represents an XML start element.
type StartElement struct {
- Name Name;
- Attr []Attr;
+ Name Name
+ Attr []Attr
}
// An EndElement represents an XML end element.
type EndElement struct {
- Name Name;
+ Name Name
}
// A CharData represents XML character data (raw text),
@@ -66,38 +66,38 @@ type EndElement struct {
type CharData []byte
func makeCopy(b []byte) []byte {
- b1 := make([]byte, len(b));
- copy(b1, b);
- return b1;
+ b1 := make([]byte, len(b))
+ copy(b1, b)
+ return b1
}
-func (c CharData) Copy() CharData { return CharData(makeCopy(c)) }
+func (c CharData) Copy() CharData { return CharData(makeCopy(c)) }
// A Comment represents an XML comment of the form <!--comment-->.
// The bytes do not include the <!-- and --> comment markers.
type Comment []byte
-func (c Comment) Copy() Comment { return Comment(makeCopy(c)) }
+func (c Comment) Copy() Comment { return Comment(makeCopy(c)) }
// A ProcInst represents an XML processing instruction of the form <?target inst?>
type ProcInst struct {
- Target string;
- Inst []byte;
+ Target string
+ Inst []byte
}
func (p ProcInst) Copy() ProcInst {
- p.Inst = makeCopy(p.Inst);
- return p;
+ p.Inst = makeCopy(p.Inst)
+ return p
}
// A Directive represents an XML directive of the form <!text>.
// The bytes do not include the <! and > markers.
type Directive []byte
-func (d Directive) Copy() Directive { return Directive(makeCopy(d)) }
+func (d Directive) Copy() Directive { return Directive(makeCopy(d)) }
type readByter interface {
- ReadByte() (b byte, err os.Error);
+ ReadByte() (b byte, err os.Error)
}
// A Parser represents an XML parser reading a particular input stream.
@@ -120,12 +120,12 @@ type Parser struct {
// p.Entity = HTMLEntity
//
// creates a parser that can handle typical HTML.
- Strict bool;
+ Strict bool
// When Strict == false, AutoClose indicates a set of elements to
// consider closed immediately after they are opened, regardless
// of whether an end element is present.
- AutoClose []string;
+ AutoClose []string
// Entity can be used to map non-standard entity names to string replacements.
// The parser behaves as if these standard mappings are present in the map,
@@ -137,20 +137,20 @@ type Parser struct {
// "pos": "'",
// "quot": `"`,
//
- Entity map[string]string;
-
- r readByter;
- buf bytes.Buffer;
- stk *stack;
- free *stack;
- needClose bool;
- toClose Name;
- nextToken Token;
- nextByte int;
- ns map[string]string;
- err os.Error;
- line int;
- tmp [32]byte;
+ Entity map[string]string
+
+ r readByter
+ buf bytes.Buffer
+ stk *stack
+ free *stack
+ needClose bool
+ toClose Name
+ nextToken Token
+ nextByte int
+ ns map[string]string
+ err os.Error
+ line int
+ tmp [32]byte
}
// NewParser creates a new XML parser reading from r.
@@ -160,7 +160,7 @@ func NewParser(r io.Reader) *Parser {
nextByte: -1,
line: 1,
Strict: true,
- };
+ }
// Get efficient byte at a time reader.
// Assume that if reader has its own
@@ -172,7 +172,7 @@ func NewParser(r io.Reader) *Parser {
p.r = bufio.NewReader(r)
}
- return p;
+ return p
}
// Token returns the next XML token in the input stream.
@@ -200,16 +200,16 @@ func NewParser(r io.Reader) *Parser {
//
func (p *Parser) Token() (t Token, err os.Error) {
if p.nextToken != nil {
- t = p.nextToken;
- p.nextToken = nil;
+ t = p.nextToken
+ p.nextToken = nil
} else if t, err = p.RawToken(); err != nil {
return
}
if !p.Strict {
if t1, ok := p.autoClose(t); ok {
- p.nextToken = t;
- t = t1;
+ p.nextToken = t
+ t = t1
}
}
switch t1 := t.(type) {
@@ -220,33 +220,33 @@ func (p *Parser) Token() (t Token, err os.Error) {
// the translations first.
for _, a := range t1.Attr {
if a.Name.Space == "xmlns" {
- v, ok := p.ns[a.Name.Local];
- p.pushNs(a.Name.Local, v, ok);
- p.ns[a.Name.Local] = a.Value;
+ v, ok := p.ns[a.Name.Local]
+ p.pushNs(a.Name.Local, v, ok)
+ p.ns[a.Name.Local] = a.Value
}
if a.Name.Space == "" && a.Name.Local == "xmlns" {
// Default space for untagged names
- v, ok := p.ns[""];
- p.pushNs("", v, ok);
- p.ns[""] = a.Value;
+ v, ok := p.ns[""]
+ p.pushNs("", v, ok)
+ p.ns[""] = a.Value
}
}
- p.translate(&t1.Name, true);
+ p.translate(&t1.Name, true)
for i := range t1.Attr {
p.translate(&t1.Attr[i].Name, false)
}
- p.pushElement(t1.Name);
- t = t1;
+ p.pushElement(t1.Name)
+ t = t1
case EndElement:
- p.translate(&t1.Name, true);
+ p.translate(&t1.Name, true)
if !p.popElement(&t1) {
return nil, p.err
}
- t = t1;
+ t = t1
}
- return;
+ return
}
// Apply name space translation to name n.
@@ -271,53 +271,53 @@ func (p *Parser) translate(n *Name, isElementName bool) {
// ending a given tag are *below* it on the stack, which is
// more work but forced on us by XML.
type stack struct {
- next *stack;
- kind int;
- name Name;
- ok bool;
+ next *stack
+ kind int
+ name Name
+ ok bool
}
const (
- stkStart = iota;
- stkNs;
+ stkStart = iota
+ stkNs
)
func (p *Parser) push(kind int) *stack {
- s := p.free;
+ s := p.free
if s != nil {
p.free = s.next
} else {
s = new(stack)
}
- s.next = p.stk;
- s.kind = kind;
- p.stk = s;
- return s;
+ s.next = p.stk
+ s.kind = kind
+ p.stk = s
+ return s
}
func (p *Parser) pop() *stack {
- s := p.stk;
+ s := p.stk
if s != nil {
- p.stk = s.next;
- s.next = p.free;
- p.free = s;
+ p.stk = s.next
+ s.next = p.free
+ p.free = s
}
- return s;
+ return s
}
// Record that we are starting an element with the given name.
func (p *Parser) pushElement(name Name) {
- s := p.push(stkStart);
- s.name = name;
+ s := p.push(stkStart)
+ s.name = name
}
// Record that we are changing the value of ns[local].
// The old value is url, ok.
func (p *Parser) pushNs(local string, url string, ok bool) {
- s := p.push(stkNs);
- s.name.Local = local;
- s.name.Space = url;
- s.ok = ok;
+ s := p.push(stkNs)
+ s.name.Local = local
+ s.name.Space = url
+ s.ok = ok
}
// Record that we are ending an element with the given name.
@@ -327,35 +327,35 @@ func (p *Parser) pushNs(local string, url string, ok bool) {
// the stack to restore the name translations that existed
// before we saw this element.
func (p *Parser) popElement(t *EndElement) bool {
- s := p.pop();
- name := t.Name;
+ s := p.pop()
+ name := t.Name
switch {
case s == nil || s.kind != stkStart:
- p.err = SyntaxError("unexpected end element </" + name.Local + ">");
- return false;
+ p.err = SyntaxError("unexpected end element </" + name.Local + ">")
+ return false
case s.name.Local != name.Local:
if !p.Strict {
- p.needClose = true;
- p.toClose = t.Name;
- t.Name = s.name;
- return true;
+ p.needClose = true
+ p.toClose = t.Name
+ t.Name = s.name
+ return true
}
- p.err = SyntaxError("element <" + s.name.Local + "> closed by </" + name.Local + ">");
- return false;
+ p.err = SyntaxError("element <" + s.name.Local + "> closed by </" + name.Local + ">")
+ return false
case s.name.Space != name.Space:
p.err = SyntaxError("element <" + s.name.Local + "> in space " + s.name.Space +
- "closed by </" + name.Local + "> in space " + name.Space);
- return false;
+ "closed by </" + name.Local + "> in space " + name.Space)
+ return false
}
// Pop stack until a Start is on the top, undoing the
// translations that were associated with the element we just closed.
for p.stk != nil && p.stk.kind != stkStart {
- s := p.pop();
- p.ns[s.name.Local] = s.name.Space, s.ok;
+ s := p.pop()
+ p.ns[s.name.Local] = s.name.Space, s.ok
}
- return true;
+ return true
}
// If the top element on the stack is autoclosing and
@@ -364,18 +364,18 @@ func (p *Parser) autoClose(t Token) (Token, bool) {
if p.stk == nil || p.stk.kind != stkStart {
return nil, false
}
- name := strings.ToLower(p.stk.name.Local);
+ name := strings.ToLower(p.stk.name.Local)
for _, s := range p.AutoClose {
if strings.ToLower(s) == name {
// This one should be auto closed if t doesn't close it.
- et, ok := t.(EndElement);
+ et, ok := t.(EndElement)
if !ok || et.Name.Local != name {
return EndElement{p.stk.name}, true
}
- break;
+ break
}
}
- return nil, false;
+ return nil, false
}
@@ -390,23 +390,23 @@ func (p *Parser) RawToken() (Token, os.Error) {
// The last element we read was self-closing and
// we returned just the StartElement half.
// Return the EndElement half now.
- p.needClose = false;
- return EndElement{p.toClose}, nil;
+ p.needClose = false
+ return EndElement{p.toClose}, nil
}
- b, ok := p.getc();
+ b, ok := p.getc()
if !ok {
return nil, p.err
}
if b != '<' {
// Text section.
- p.ungetc(b);
- data := p.text(-1, false);
+ p.ungetc(b)
+ data := p.text(-1, false)
if data == nil {
return nil, p.err
}
- return CharData(data), nil;
+ return CharData(data), nil
}
if b, ok = p.mustgetc(); !ok {
@@ -415,50 +415,50 @@ func (p *Parser) RawToken() (Token, os.Error) {
switch b {
case '/':
// </: End element
- var name Name;
+ var name Name
if name, ok = p.nsname(); !ok {
if p.err == nil {
p.err = SyntaxError("expected element name after </")
}
- return nil, p.err;
+ return nil, p.err
}
- p.space();
+ p.space()
if b, ok = p.mustgetc(); !ok {
return nil, p.err
}
if b != '>' {
- p.err = SyntaxError("invalid characters between </" + name.Local + " and >");
- return nil, p.err;
+ p.err = SyntaxError("invalid characters between </" + name.Local + " and >")
+ return nil, p.err
}
- return EndElement{name}, nil;
+ return EndElement{name}, nil
case '?':
// <?: Processing instruction.
// TODO(rsc): Should parse the <?xml declaration to make sure
// the version is 1.0 and the encoding is UTF-8.
- var target string;
+ var target string
if target, ok = p.name(); !ok {
if p.err == nil {
p.err = SyntaxError("expected target name after <?")
}
- return nil, p.err;
+ return nil, p.err
}
- p.space();
- p.buf.Reset();
- var b0 byte;
+ p.space()
+ p.buf.Reset()
+ var b0 byte
for {
if b, ok = p.mustgetc(); !ok {
return nil, p.err
}
- p.buf.WriteByte(b);
+ p.buf.WriteByte(b)
if b0 == '?' && b == '>' {
break
}
- b0 = b;
+ b0 = b
}
- data := p.buf.Bytes();
- data = data[0 : len(data)-2]; // chop ?>
- return ProcInst{target, data}, nil;
+ data := p.buf.Bytes()
+ data = data[0 : len(data)-2] // chop ?>
+ return ProcInst{target, data}, nil
case '!':
// <!: Maybe comment, maybe CDATA.
@@ -466,55 +466,55 @@ func (p *Parser) RawToken() (Token, os.Error) {
return nil, p.err
}
switch b {
- case '-': // <!-
+ case '-': // <!-
// Probably <!-- for a comment.
if b, ok = p.mustgetc(); !ok {
return nil, p.err
}
if b != '-' {
- p.err = SyntaxError("invalid sequence <!- not part of <!--");
- return nil, p.err;
+ p.err = SyntaxError("invalid sequence <!- not part of <!--")
+ return nil, p.err
}
// Look for terminator.
- p.buf.Reset();
- var b0, b1 byte;
+ p.buf.Reset()
+ var b0, b1 byte
for {
if b, ok = p.mustgetc(); !ok {
return nil, p.err
}
- p.buf.WriteByte(b);
+ p.buf.WriteByte(b)
if b0 == '-' && b1 == '-' && b == '>' {
break
}
- b0, b1 = b1, b;
+ b0, b1 = b1, b
}
- data := p.buf.Bytes();
- data = data[0 : len(data)-3]; // chop -->
- return Comment(data), nil;
+ data := p.buf.Bytes()
+ data = data[0 : len(data)-3] // chop -->
+ return Comment(data), nil
- case '[': // <![
+ case '[': // <![
// Probably <![CDATA[.
for i := 0; i < 6; i++ {
if b, ok = p.mustgetc(); !ok {
return nil, p.err
}
if b != "CDATA["[i] {
- p.err = SyntaxError("invalid <![ sequence");
- return nil, p.err;
+ p.err = SyntaxError("invalid <![ sequence")
+ return nil, p.err
}
}
// Have <![CDATA[. Read text until ]]>.
- data := p.text(-1, true);
+ data := p.text(-1, true)
if data == nil {
return nil, p.err
}
- return CharData(data), nil;
+ return CharData(data), nil
}
// Probably a directive: <!DOCTYPE ...>, <!ENTITY ...>, etc.
// We don't care, but accumulate for caller.
- p.buf.Reset();
- p.buf.WriteByte(b);
+ p.buf.Reset()
+ p.buf.WriteByte(b)
for {
if b, ok = p.mustgetc(); !ok {
return nil, p.err
@@ -522,106 +522,106 @@ func (p *Parser) RawToken() (Token, os.Error) {
if b == '>' {
break
}
- p.buf.WriteByte(b);
+ p.buf.WriteByte(b)
}
- return Directive(p.buf.Bytes()), nil;
+ return Directive(p.buf.Bytes()), nil
}
// Must be an open element like <a href="foo">
- p.ungetc(b);
+ p.ungetc(b)
var (
- name Name;
- empty bool;
- attr []Attr;
+ name Name
+ empty bool
+ attr []Attr
)
if name, ok = p.nsname(); !ok {
if p.err == nil {
p.err = SyntaxError("expected element name after <")
}
- return nil, p.err;
+ return nil, p.err
}
- attr = make([]Attr, 0, 4);
+ attr = make([]Attr, 0, 4)
for {
- p.space();
+ p.space()
if b, ok = p.mustgetc(); !ok {
return nil, p.err
}
if b == '/' {
- empty = true;
+ empty = true
if b, ok = p.mustgetc(); !ok {
return nil, p.err
}
if b != '>' {
- p.err = SyntaxError("expected /> in element");
- return nil, p.err;
+ p.err = SyntaxError("expected /> in element")
+ return nil, p.err
}
- break;
+ break
}
if b == '>' {
break
}
- p.ungetc(b);
+ p.ungetc(b)
- n := len(attr);
+ n := len(attr)
if n >= cap(attr) {
- nattr := make([]Attr, n, 2*cap(attr));
+ nattr := make([]Attr, n, 2*cap(attr))
for i, a := range attr {
nattr[i] = a
}
- attr = nattr;
+ attr = nattr
}
- attr = attr[0 : n+1];
- a := &attr[n];
+ attr = attr[0 : n+1]
+ a := &attr[n]
if a.Name, ok = p.nsname(); !ok {
if p.err == nil {
p.err = SyntaxError("expected attribute name in element")
}
- return nil, p.err;
+ return nil, p.err
}
- p.space();
+ p.space()
if b, ok = p.mustgetc(); !ok {
return nil, p.err
}
if b != '=' {
- p.err = SyntaxError("attribute name without = in element");
- return nil, p.err;
+ p.err = SyntaxError("attribute name without = in element")
+ return nil, p.err
}
- p.space();
+ p.space()
if b, ok = p.mustgetc(); !ok {
return nil, p.err
}
if b != '"' && b != '\'' {
- p.err = SyntaxError("unquoted or missing attribute value in element");
- return nil, p.err;
+ p.err = SyntaxError("unquoted or missing attribute value in element")
+ return nil, p.err
}
- data := p.text(int(b), false);
+ data := p.text(int(b), false)
if data == nil {
return nil, p.err
}
- a.Value = string(data);
+ a.Value = string(data)
}
if empty {
- p.needClose = true;
- p.toClose = name;
+ p.needClose = true
+ p.toClose = name
}
- return StartElement{name, attr}, nil;
+ return StartElement{name, attr}, nil
}
// Skip spaces if any
func (p *Parser) space() {
for {
- b, ok := p.getc();
+ b, ok := p.getc()
if !ok {
return
}
switch b {
case ' ', '\r', '\n', '\t':
default:
- p.ungetc(b);
- return;
+ p.ungetc(b)
+ return
}
}
}
@@ -635,10 +635,10 @@ func (p *Parser) getc() (b byte, ok bool) {
return 0, false
}
if p.nextByte >= 0 {
- b = byte(p.nextByte);
- p.nextByte = -1;
+ b = byte(p.nextByte)
+ p.nextByte = -1
} else {
- b, p.err = p.r.ReadByte();
+ b, p.err = p.r.ReadByte()
if p.err != nil {
return 0, false
}
@@ -646,7 +646,7 @@ func (p *Parser) getc() (b byte, ok bool) {
if b == '\n' {
p.line++
}
- return b, true;
+ return b, true
}
// Must read a single byte.
@@ -659,7 +659,7 @@ func (p *Parser) mustgetc() (b byte, ok bool) {
p.err = SyntaxError("unexpected EOF")
}
}
- return;
+ return
}
// Unread a single byte.
@@ -667,7 +667,7 @@ func (p *Parser) ungetc(b byte) {
if b == '\n' {
p.line--
}
- p.nextByte = int(b);
+ p.nextByte = int(b)
}
var entity = map[string]int{
@@ -683,12 +683,12 @@ var entity = map[string]int{
// If cdata == true, we are in a <![CDATA[ section and need to find ]]>.
// On failure return nil and leave the error in p.err.
func (p *Parser) text(quote int, cdata bool) []byte {
- var b0, b1 byte;
- var trunc int;
- p.buf.Reset();
+ var b0, b1 byte
+ var trunc int
+ p.buf.Reset()
Input:
for {
- b, ok := p.mustgetc();
+ b, ok := p.mustgetc()
if !ok {
return nil
}
@@ -697,21 +697,21 @@ Input:
// It is an error for ]]> to appear in ordinary text.
if b0 == ']' && b1 == ']' && b == '>' {
if cdata {
- trunc = 2;
- break Input;
+ trunc = 2
+ break Input
}
- p.err = SyntaxError("unescaped ]]> not in CDATA section");
- return nil;
+ p.err = SyntaxError("unescaped ]]> not in CDATA section")
+ return nil
}
// Stop reading text if we see a <.
if b == '<' && !cdata {
if quote >= 0 {
- p.err = SyntaxError("unescaped < inside quoted string");
- return nil;
+ p.err = SyntaxError("unescaped < inside quoted string")
+ return nil
}
- p.ungetc('<');
- break Input;
+ p.ungetc('<')
+ break Input
}
if quote >= 0 && b == byte(quote) {
break Input
@@ -722,17 +722,17 @@ Input:
// its own character names with <!ENTITY ...> directives.
// Parsers are required to recognize lt, gt, amp, apos, and quot
// even if they have not been declared. That's all we allow.
- var i int;
+ var i int
CharLoop:
for i = 0; i < len(p.tmp); i++ {
- p.tmp[i], p.err = p.r.ReadByte();
+ p.tmp[i], p.err = p.r.ReadByte()
if p.err != nil {
if p.err == os.EOF {
p.err = SyntaxError("unexpected EOF")
}
- return nil;
+ return nil
}
- c := p.tmp[i];
+ c := p.tmp[i]
if c == ';' {
break
}
@@ -742,131 +742,131 @@ Input:
c == '_' || c == '#' {
continue
}
- p.ungetc(c);
- break;
+ p.ungetc(c)
+ break
}
- s := string(p.tmp[0:i]);
+ s := string(p.tmp[0:i])
if i >= len(p.tmp) {
if !p.Strict {
- b0, b1 = 0, 0;
- p.buf.WriteByte('&');
- p.buf.Write(p.tmp[0:i]);
- continue Input;
+ b0, b1 = 0, 0
+ p.buf.WriteByte('&')
+ p.buf.Write(p.tmp[0:i])
+ continue Input
}
- p.err = SyntaxError("character entity expression &" + s + "... too long");
- return nil;
+ p.err = SyntaxError("character entity expression &" + s + "... too long")
+ return nil
}
- var haveText bool;
- var text string;
+ var haveText bool
+ var text string
if i >= 2 && s[0] == '#' {
- var n uint64;
- var err os.Error;
+ var n uint64
+ var err os.Error
if i >= 3 && s[1] == 'x' {
n, err = strconv.Btoui64(s[2:], 16)
} else {
n, err = strconv.Btoui64(s[1:], 10)
}
if err == nil && n <= unicode.MaxRune {
- text = string(n);
- haveText = true;
+ text = string(n)
+ haveText = true
}
} else {
if r, ok := entity[s]; ok {
- text = string(r);
- haveText = true;
+ text = string(r)
+ haveText = true
} else if p.Entity != nil {
text, haveText = p.Entity[s]
}
}
if !haveText {
if !p.Strict {
- b0, b1 = 0, 0;
- p.buf.WriteByte('&');
- p.buf.Write(p.tmp[0:i]);
- continue Input;
+ b0, b1 = 0, 0
+ p.buf.WriteByte('&')
+ p.buf.Write(p.tmp[0:i])
+ continue Input
}
- p.err = SyntaxError("invalid character entity &" + s + ";");
- return nil;
+ p.err = SyntaxError("invalid character entity &" + s + ";")
+ return nil
}
- p.buf.Write(strings.Bytes(text));
- b0, b1 = 0, 0;
- continue Input;
+ p.buf.Write(strings.Bytes(text))
+ b0, b1 = 0, 0
+ continue Input
}
- p.buf.WriteByte(b);
- b0, b1 = b1, b;
+ p.buf.WriteByte(b)
+ b0, b1 = b1, b
}
- data := p.buf.Bytes();
- data = data[0 : len(data)-trunc];
+ data := p.buf.Bytes()
+ data = data[0 : len(data)-trunc]
// Must rewrite \r and \r\n into \n.
- w := 0;
+ w := 0
for r := 0; r < len(data); r++ {
- b := data[r];
+ b := data[r]
if b == '\r' {
if r+1 < len(data) && data[r+1] == '\n' {
continue
}
- b = '\n';
+ b = '\n'
}
- data[w] = b;
- w++;
+ data[w] = b
+ w++
}
- return data[0:w];
+ return data[0:w]
}
// Get name space name: name with a : stuck in the middle.
// The part before the : is the name space identifier.
func (p *Parser) nsname() (name Name, ok bool) {
- s, ok := p.name();
+ s, ok := p.name()
if !ok {
return
}
- i := strings.Index(s, ":");
+ i := strings.Index(s, ":")
if i < 0 {
name.Local = s
} else {
- name.Space = s[0:i];
- name.Local = s[i+1:];
+ name.Space = s[0:i]
+ name.Local = s[i+1:]
}
- return name, true;
+ return name, true
}
// Get name: /first(first|second)*/
// Do not set p.err if the name is missing (unless unexpected EOF is received):
// let the caller provide better context.
func (p *Parser) name() (s string, ok bool) {
- var b byte;
+ var b byte
if b, ok = p.mustgetc(); !ok {
return
}
// As a first approximation, we gather the bytes [A-Za-z_:.-\x80-\xFF]*
if b < utf8.RuneSelf && !isNameByte(b) {
- p.ungetc(b);
- return "", false;
+ p.ungetc(b)
+ return "", false
}
- p.buf.Reset();
- p.buf.WriteByte(b);
+ p.buf.Reset()
+ p.buf.WriteByte(b)
for {
if b, ok = p.mustgetc(); !ok {
return
}
if b < utf8.RuneSelf && !isNameByte(b) {
- p.ungetc(b);
- break;
+ p.ungetc(b)
+ break
}
- p.buf.WriteByte(b);
+ p.buf.WriteByte(b)
}
// Then we check the characters.
- s = p.buf.String();
+ s = p.buf.String()
for i, c := range s {
if !unicode.Is(first, c) && (i == 0 || !unicode.Is(second, c)) {
- p.err = SyntaxError("invalid XML name: " + s);
- return "", false;
+ p.err = SyntaxError("invalid XML name: " + s)
+ return "", false
}
}
- return s, true;
+ return s, true
}
func isNameByte(c byte) bool {