diff options
| author | Russ Cox <rsc@golang.org> | 2010-04-21 16:27:31 -0700 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2010-04-21 16:27:31 -0700 |
| commit | 26634e5741a84a4893315ab76333269078faf6ec (patch) | |
| tree | 5566b8d8e619953739ffc53d825d3e16613356b3 /src/pkg/xml/read.go | |
| parent | 7c298c744f5477f352fdc1d5acf01710f79e34f2 (diff) | |
| download | golang-26634e5741a84a4893315ab76333269078faf6ec.tar.gz | |
xml: new "innerxml" tag to collect inner XML
R=r
CC=golang-dev
http://codereview.appspot.com/971041
Diffstat (limited to 'src/pkg/xml/read.go')
| -rw-r--r-- | src/pkg/xml/read.go | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/src/pkg/xml/read.go b/src/pkg/xml/read.go index 45db7daa3..9204660b3 100644 --- a/src/pkg/xml/read.go +++ b/src/pkg/xml/read.go @@ -76,6 +76,10 @@ import ( // // Unmarshal maps an XML element to a struct using the following rules: // +// * If the struct has a field of type []byte or string with tag "innerxml", +// Unmarshal accumulates the raw XML nested inside the element +// in that field. The rest of the rules still apply. +// // * If the struct has a field named XMLName of type xml.Name, // Unmarshal records the element name in that field. // @@ -198,12 +202,15 @@ func (p *Parser) unmarshal(val reflect.Value, start *StartElement) os.Error { } var ( - data []byte - saveData reflect.Value - comment []byte - saveComment reflect.Value - sv *reflect.StructValue - styp *reflect.StructType + data []byte + saveData reflect.Value + comment []byte + saveComment reflect.Value + saveXML reflect.Value + saveXMLIndex int + saveXMLData []byte + sv *reflect.StructValue + styp *reflect.StructType ) switch v := val.(type) { default: @@ -316,6 +323,17 @@ func (p *Parser) unmarshal(val reflect.Value, start *StartElement) os.Error { if saveData == nil { saveData = sv.FieldByIndex(f.Index) } + + case "innerxml": + if saveXML == nil { + saveXML = sv.FieldByIndex(f.Index) + if p.saved == nil { + saveXMLIndex = 0 + p.saved = new(bytes.Buffer) + } else { + saveXMLIndex = p.savedOffset() + } + } } } } @@ -324,6 +342,10 @@ func (p *Parser) unmarshal(val reflect.Value, start *StartElement) os.Error { // Process sub-elements along the way. Loop: for { + var savedOffset int + if saveXML != nil { + savedOffset = p.savedOffset() + } tok, err := p.Token() if err != nil { return err @@ -361,6 +383,12 @@ Loop: } case EndElement: + if saveXML != nil { + saveXMLData = p.saved.Bytes()[saveXMLIndex:savedOffset] + if saveXMLIndex == 0 { + p.saved = nil + } + } break Loop case CharData: @@ -491,6 +519,13 @@ Loop: t.Set(reflect.NewValue(comment).(*reflect.SliceValue)) } + switch t := saveXML.(type) { + case *reflect.StringValue: + t.Set(string(saveXMLData)) + case *reflect.SliceValue: + t.Set(reflect.NewValue(saveXMLData).(*reflect.SliceValue)) + } + return nil } |
