Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
e7b6fe39
Commit
e7b6fe39
authored
Apr 21, 2010
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
xml: new "innerxml" tag to collect inner XML
R=r CC=golang-dev
https://golang.org/cl/971041
parent
57d9de3a
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
66 additions
and
13 deletions
+66
-13
src/pkg/xml/read.go
src/pkg/xml/read.go
+41
-6
src/pkg/xml/read_test.go
src/pkg/xml/read_test.go
+11
-7
src/pkg/xml/xml.go
src/pkg/xml/xml.go
+14
-0
No files found.
src/pkg/xml/read.go
View file @
e7b6fe39
...
@@ -76,6 +76,10 @@ import (
...
@@ -76,6 +76,10 @@ import (
//
//
// Unmarshal maps an XML element to a struct using the following rules:
// 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,
// * If the struct has a field named XMLName of type xml.Name,
// Unmarshal records the element name in that field.
// Unmarshal records the element name in that field.
//
//
...
@@ -198,12 +202,15 @@ func (p *Parser) unmarshal(val reflect.Value, start *StartElement) os.Error {
...
@@ -198,12 +202,15 @@ func (p *Parser) unmarshal(val reflect.Value, start *StartElement) os.Error {
}
}
var
(
var
(
data
[]
byte
data
[]
byte
saveData
reflect
.
Value
saveData
reflect
.
Value
comment
[]
byte
comment
[]
byte
saveComment
reflect
.
Value
saveComment
reflect
.
Value
sv
*
reflect
.
StructValue
saveXML
reflect
.
Value
styp
*
reflect
.
StructType
saveXMLIndex
int
saveXMLData
[]
byte
sv
*
reflect
.
StructValue
styp
*
reflect
.
StructType
)
)
switch
v
:=
val
.
(
type
)
{
switch
v
:=
val
.
(
type
)
{
default
:
default
:
...
@@ -316,6 +323,17 @@ func (p *Parser) unmarshal(val reflect.Value, start *StartElement) os.Error {
...
@@ -316,6 +323,17 @@ func (p *Parser) unmarshal(val reflect.Value, start *StartElement) os.Error {
if
saveData
==
nil
{
if
saveData
==
nil
{
saveData
=
sv
.
FieldByIndex
(
f
.
Index
)
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 {
...
@@ -324,6 +342,10 @@ func (p *Parser) unmarshal(val reflect.Value, start *StartElement) os.Error {
// Process sub-elements along the way.
// Process sub-elements along the way.
Loop
:
Loop
:
for
{
for
{
var
savedOffset
int
if
saveXML
!=
nil
{
savedOffset
=
p
.
savedOffset
()
}
tok
,
err
:=
p
.
Token
()
tok
,
err
:=
p
.
Token
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
@@ -361,6 +383,12 @@ Loop:
...
@@ -361,6 +383,12 @@ Loop:
}
}
case
EndElement
:
case
EndElement
:
if
saveXML
!=
nil
{
saveXMLData
=
p
.
saved
.
Bytes
()[
saveXMLIndex
:
savedOffset
]
if
saveXMLIndex
==
0
{
p
.
saved
=
nil
}
}
break
Loop
break
Loop
case
CharData
:
case
CharData
:
...
@@ -491,6 +519,13 @@ Loop:
...
@@ -491,6 +519,13 @@ Loop:
t
.
Set
(
reflect
.
NewValue
(
comment
)
.
(
*
reflect
.
SliceValue
))
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
return
nil
}
}
...
...
src/pkg/xml/read_test.go
View file @
e7b6fe39
...
@@ -17,7 +17,7 @@ func TestUnmarshalFeed(t *testing.T) {
...
@@ -17,7 +17,7 @@ func TestUnmarshalFeed(t *testing.T) {
t
.
Fatalf
(
"Unmarshal: %s"
,
err
)
t
.
Fatalf
(
"Unmarshal: %s"
,
err
)
}
}
if
!
reflect
.
DeepEqual
(
f
,
rssFeed
)
{
if
!
reflect
.
DeepEqual
(
f
,
rssFeed
)
{
t
.
Fatalf
(
"have %#v
\n
want %#v
\n\n
%#v"
,
f
)
t
.
Fatalf
(
"have %#v
\n
want %#v
"
,
f
,
rssFeed
)
}
}
}
}
...
@@ -102,9 +102,10 @@ type Link struct {
...
@@ -102,9 +102,10 @@ type Link struct {
}
}
type
Person
struct
{
type
Person
struct
{
Name
string
Name
string
URI
string
URI
string
Email
string
Email
string
InnerXML
string
"innerxml"
}
}
type
Text
struct
{
type
Text
struct
{
...
@@ -124,7 +125,8 @@ var rssFeed = Feed{
...
@@ -124,7 +125,8 @@ var rssFeed = Feed{
Id
:
"http://codereview.appspot.com/"
,
Id
:
"http://codereview.appspot.com/"
,
Updated
:
"2009-10-04T01:35:58+00:00"
,
Updated
:
"2009-10-04T01:35:58+00:00"
,
Author
:
Person
{
Author
:
Person
{
Name
:
"rietveld"
,
Name
:
"rietveld"
,
InnerXML
:
"<name>rietveld</name>"
,
},
},
Entry
:
[]
Entry
{
Entry
:
[]
Entry
{
Entry
{
Entry
{
...
@@ -134,7 +136,8 @@ var rssFeed = Feed{
...
@@ -134,7 +136,8 @@ var rssFeed = Feed{
},
},
Updated
:
"2009-10-04T01:35:58+00:00"
,
Updated
:
"2009-10-04T01:35:58+00:00"
,
Author
:
Person
{
Author
:
Person
{
Name
:
"email-address-removed"
,
Name
:
"email-address-removed"
,
InnerXML
:
"<name>email-address-removed</name>"
,
},
},
Id
:
"urn:md5:134d9179c41f806be79b3a5f7877d19a"
,
Id
:
"urn:md5:134d9179c41f806be79b3a5f7877d19a"
,
Summary
:
Text
{
Summary
:
Text
{
...
@@ -180,7 +183,8 @@ the top of feeds.py marked NOTE(rsc).
...
@@ -180,7 +183,8 @@ the top of feeds.py marked NOTE(rsc).
},
},
Updated
:
"2009-10-03T23:02:17+00:00"
,
Updated
:
"2009-10-03T23:02:17+00:00"
,
Author
:
Person
{
Author
:
Person
{
Name
:
"email-address-removed"
,
Name
:
"email-address-removed"
,
InnerXML
:
"<name>email-address-removed</name>"
,
},
},
Id
:
"urn:md5:0a2a4f19bb815101f0ba2904aed7c35a"
,
Id
:
"urn:md5:0a2a4f19bb815101f0ba2904aed7c35a"
,
Summary
:
Text
{
Summary
:
Text
{
...
...
src/pkg/xml/xml.go
View file @
e7b6fe39
...
@@ -165,6 +165,7 @@ type Parser struct {
...
@@ -165,6 +165,7 @@ type Parser struct {
r
io
.
ReadByter
r
io
.
ReadByter
buf
bytes
.
Buffer
buf
bytes
.
Buffer
saved
*
bytes
.
Buffer
stk
*
stack
stk
*
stack
free
*
stack
free
*
stack
needClose
bool
needClose
bool
...
@@ -698,6 +699,9 @@ func (p *Parser) getc() (b byte, ok bool) {
...
@@ -698,6 +699,9 @@ func (p *Parser) getc() (b byte, ok bool) {
if
p
.
err
!=
nil
{
if
p
.
err
!=
nil
{
return
0
,
false
return
0
,
false
}
}
if
p
.
saved
!=
nil
{
p
.
saved
.
WriteByte
(
b
)
}
}
}
if
b
==
'\n'
{
if
b
==
'\n'
{
p
.
line
++
p
.
line
++
...
@@ -705,6 +709,16 @@ func (p *Parser) getc() (b byte, ok bool) {
...
@@ -705,6 +709,16 @@ func (p *Parser) getc() (b byte, ok bool) {
return
b
,
true
return
b
,
true
}
}
// Return saved offset.
// If we did ungetc (nextByte >= 0), have to back up one.
func
(
p
*
Parser
)
savedOffset
()
int
{
n
:=
p
.
saved
.
Len
()
if
p
.
nextByte
>=
0
{
n
--
}
return
n
}
// Must read a single byte.
// Must read a single byte.
// If there is no byte to read,
// If there is no byte to read,
// set p.err to SyntaxError("unexpected EOF")
// set p.err to SyntaxError("unexpected EOF")
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment