@@ -16,6 +16,7 @@ import (
16
16
"log"
17
17
"os"
18
18
"regexp"
19
+ "strings"
19
20
20
21
"github.com/DavidGamba/go-getoptions"
21
22
"github.com/DavidGamba/xmlsect/semver"
@@ -61,6 +62,100 @@ func printNodeSet(n []dom.Node) {
61
62
}
62
63
}
63
64
65
+ func printNodeSetTree (n []dom.Node ) {
66
+ var str string
67
+ l := len (n )
68
+ for i , e := range n {
69
+ str += printTreeNode (e , 0 )
70
+ if i + 1 < l {
71
+ str += "\n "
72
+ }
73
+ }
74
+ fmt .Println (str )
75
+ }
76
+
77
+ // Taken and modified from github.com/santhosh-tekuri/dom/marshal.go
78
+ //
79
+ // Copyright 2017 Santhosh Kumar Tekuri. All rights reserved.
80
+ // Use of this source code is governed by a BSD-style
81
+ // license that can be found in the LICENSE file.
82
+ //
83
+ func printName (n * dom.Name ) string {
84
+ var str string
85
+ if n .Prefix != "" {
86
+ str += n .Prefix
87
+ str += ":"
88
+ }
89
+ str += n .Local
90
+ return str
91
+ }
92
+
93
+ // Taken and modified from github.com/santhosh-tekuri/dom/marshal.go
94
+ //
95
+ // Copyright 2017 Santhosh Kumar Tekuri. All rights reserved.
96
+ // Use of this source code is governed by a BSD-style
97
+ // license that can be found in the LICENSE file.
98
+ //
99
+ func printTreeNode (n dom.Node , level int ) string {
100
+ var str string
101
+ switch n := n .(type ) {
102
+ case * dom.Document :
103
+ log .Printf ("Document. Children %d\n " , len (n .Children ()))
104
+ for _ , c := range n .Children () {
105
+ str += printTreeNode (c , level + 1 )
106
+ }
107
+ case * dom.Element :
108
+ str += "/"
109
+ str += printName (n .Name )
110
+ for prefix , _ := range n .NSDecl {
111
+ str += " "
112
+ str += "xmlns"
113
+ if prefix != "" {
114
+ str += ":"
115
+ str += prefix
116
+ }
117
+ }
118
+ for _ , attr := range n .Attrs {
119
+ str += " @"
120
+ str += printName (attr .Name )
121
+ }
122
+ if len (n .Children ()) != 0 {
123
+ log .Printf ("Element '%s' Children %d\n " , n .Name , len (n .ChildNodes ))
124
+ unique := make (map [string ]int )
125
+ for _ , c := range n .Children () {
126
+ tmpStr := printTreeNode (c , level + 1 )
127
+ // Skip empty results
128
+ if tmpStr == "" {
129
+ continue
130
+ }
131
+ if v , ok := unique [tmpStr ]; ok {
132
+ count := v + 1
133
+ unique [tmpStr ] = count
134
+ } else {
135
+ unique [tmpStr ] = 1
136
+ }
137
+ }
138
+ for k , v := range unique {
139
+ if strings .HasPrefix (k , "/" ) {
140
+ str += "\n "
141
+ str += strings .Repeat (" " , level + 1 )
142
+ str += fmt .Sprintf ("[%d] %s" , v , k )
143
+ } else {
144
+ str += fmt .Sprintf ("%s" , k )
145
+ }
146
+ }
147
+ }
148
+ case * dom.Text :
149
+ r := regexp .MustCompile (`^\n\s+$|^\s+$` )
150
+ if ! r .Match ([]byte (n .Data )) {
151
+ str += " text"
152
+ }
153
+ case * dom.ProcInst :
154
+ // TODO
155
+ }
156
+ return str
157
+ }
158
+
64
159
func printDoc (doc * dom.Document ) {
65
160
buf := new (bytes.Buffer )
66
161
if err := dom .Marshal (doc , buf ); err != nil {
@@ -72,7 +167,7 @@ func printDoc(doc *dom.Document) {
72
167
73
168
func synopsis () {
74
169
synopsis := `# USAGE:
75
- xsect <file> [<xpath>] [<relative_xpath>]
170
+ xsect <file> [<xpath>] [<relative_xpath>] [--tree]
76
171
77
172
xsect [--help]
78
173
`
@@ -84,6 +179,7 @@ func main() {
84
179
opt .Bool ("help" , false )
85
180
opt .Bool ("debug" , false )
86
181
opt .Bool ("version" , false )
182
+ opt .Bool ("tree" , false )
87
183
remaining , err := opt .Parse (os .Args [1 :])
88
184
if err != nil {
89
185
fmt .Fprintf (os .Stderr , "ERROR: %s\n " , err )
@@ -148,6 +244,10 @@ func main() {
148
244
os .Exit (1 )
149
245
}
150
246
log .Printf ("results: %d\n " , len (nodeSet ))
247
+ if opt .Called ("tree" ) {
248
+ printNodeSetTree (nodeSet )
249
+ os .Exit (0 )
250
+ }
151
251
printNodeSet (nodeSet )
152
252
if xpathRelQuery != "" {
153
253
doc := & dom.Document {nodeSet }
0 commit comments