Skip to content

Commit a1f6ff8

Browse files
author
Rener
committed
#11 ParseAttributesOnly
1 parent ac36c34 commit a1f6ff8

File tree

3 files changed

+45
-10
lines changed

3 files changed

+45
-10
lines changed

sample.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
<!ELEMENT para (#PCDATA)>
88
]>
99
<!-- Comment at top after declarations -->
10-
<examples>
10+
<examples att1="ex1" att2="ex2">
1111
<tag1 att1="<att0>" att2="att0">
12-
<tag11 att1="att0">Hello <![CDATA[你好]]> <!-- comment --><![CDATA[Gür]]></tag11>
12+
<tag11 att1="att0">Hello <![CDATA[你好]]> <!-- comment --><![CDATA[Gür]]></tag11>
1313
<tag11 att1="att0">InnerText111</tag11>
1414
<tag12 att1="att0"/>
1515
<tag13>InnerText13</tag13>

xmlparser.go

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ type XMLParser struct {
1212
loopElements map[string]bool
1313
resultChannel chan *XMLElement
1414
skipElements map[string]bool
15+
attrOnlyElements map[string]bool
1516
skipOuterElements bool
1617
xpathEnabled bool
1718
scratch *scratch
@@ -22,12 +23,13 @@ type XMLParser struct {
2223
func NewXMLParser(reader *bufio.Reader, loopElements ...string) *XMLParser {
2324

2425
x := &XMLParser{
25-
reader: reader,
26-
loopElements: map[string]bool{},
27-
resultChannel: make(chan *XMLElement, 256),
28-
skipElements: map[string]bool{},
29-
scratch: &scratch{data: make([]byte, 1024)},
30-
scratch2: &scratch{data: make([]byte, 1024)},
26+
reader: reader,
27+
loopElements: map[string]bool{},
28+
attrOnlyElements: map[string]bool{},
29+
resultChannel: make(chan *XMLElement, 256),
30+
skipElements: map[string]bool{},
31+
scratch: &scratch{data: make([]byte, 1024)},
32+
scratch2: &scratch{data: make([]byte, 1024)},
3133
}
3234

3335
// Register loop elements
@@ -49,6 +51,13 @@ func (x *XMLParser) SkipElements(skipElements []string) *XMLParser {
4951

5052
}
5153

54+
func (x *XMLParser) ParseAttributesOnly(loopElements ...string) *XMLParser {
55+
for _, e := range loopElements {
56+
x.attrOnlyElements[e] = true
57+
}
58+
return x
59+
}
60+
5261
// by default skip elements works for stream elements childs
5362
// if this method called parser skip also outer elements
5463
func (x *XMLParser) SkipOuterElements() *XMLParser {
@@ -136,7 +145,9 @@ func (x *XMLParser) parse() {
136145
continue
137146
}
138147

139-
element = x.getElementTree(element)
148+
if _, only := x.attrOnlyElements[element.Name]; !only {
149+
element = x.getElementTree(element)
150+
}
140151
x.resultChannel <- element
141152
if element.Err != nil {
142153
return

xmlparser_test.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func TestBasics(t *testing.T) {
5050
panic("Test failed")
5151
}
5252

53-
if results[0].Childs["tag11"][0].InnerText != "Hello 你好 Gür" {
53+
if results[0].Childs["tag11"][0].InnerText != "Hello 你好 Gür" {
5454
panic("Test failed")
5555
}
5656

@@ -408,6 +408,30 @@ func TestXpathNS(t *testing.T) {
408408

409409
}
410410

411+
func TestAttrOnly(t *testing.T) {
412+
p := getparser("examples", "tag1").ParseAttributesOnly("examples")
413+
for xml := range p.Stream() {
414+
if xml.Err != nil {
415+
t.Fatal(xml.Err)
416+
}
417+
if xml.Name == "examples" {
418+
if len(xml.Childs) != 0 {
419+
t.Fatal("Childs not empty for ParseAttributesOnly tags")
420+
}
421+
fmt.Printf("Name: \t%s\n", xml.Name)
422+
fmt.Printf("Attrs: \t%v\n\n", xml.Attrs)
423+
}
424+
if xml.Name == "tag1" {
425+
if len(xml.Childs) == 0 {
426+
t.Fatal("Childs not empty for ParseAttributesOnly tags")
427+
}
428+
fmt.Printf("Name: \t%s\n", xml.Name)
429+
fmt.Printf("Attrs: \t%v\n", xml.Attrs)
430+
fmt.Printf("Childs: %v\n", xml.Childs)
431+
}
432+
}
433+
}
434+
411435
func Benchmark1(b *testing.B) {
412436

413437
for n := 0; n < b.N; n++ {

0 commit comments

Comments
 (0)