forked from mantyr/go-xmldom
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprint.go
121 lines (108 loc) · 2.77 KB
/
print.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package xmldom
import (
"bytes"
"encoding/xml"
"fmt"
"strings"
)
func stringifyProcInst(pi *xml.ProcInst) string {
if pi == nil {
return ""
}
return fmt.Sprintf("<?%s %s?>", pi.Target, string(pi.Inst))
}
func stringifyDirective(directive *xml.Directive) string {
if directive == nil {
return ""
}
return fmt.Sprintf("<!%s>", string(*directive))
}
type printer struct{}
func (p *printer) printXML(buf *bytes.Buffer, n *Node, level int, indent string) {
pretty := len(indent) > 0
if pretty {
buf.WriteString(strings.Repeat(indent, level))
}
space := n.GetNamespace()
buf.WriteByte('<')
if space != nil {
buf.WriteString(space.Name.Local)
buf.WriteByte(':')
}
buf.WriteString(n.Name.Local)
// наследование xmlns от вышестоящего элемента если он есть
if level == 0 && n.Name.Space != "" && space != nil {
// для тех случаев когда нужно распечатать часть большого XML, например Signature/SignedInfo
buf.WriteByte(' ')
buf.WriteString(space.Name.Space)
buf.WriteByte(':')
buf.WriteString(space.Name.Local)
buf.WriteByte('=')
buf.WriteByte('"')
xml.Escape(buf, []byte(space.Value))
buf.WriteByte('"')
}
if len(n.Attributes) > 0 {
for _, attr := range n.Attributes {
if attr.Name.Space == "" {
buf.WriteByte(' ')
buf.WriteString(attr.Name.Local)
buf.WriteByte('=')
buf.WriteByte('"')
xml.Escape(buf, []byte(attr.Value))
buf.WriteByte('"')
} else if attr.Name.Space == "xmlns" {
// выставляем xmlns для тех тегов где он был изначально прописан,
// игнорируем первый тег так как для него уже есть условие
if level > 0 && space != nil {
buf.WriteByte(' ')
buf.WriteString(attr.Name.Space)
buf.WriteByte(':')
buf.WriteString(attr.Name.Local)
buf.WriteByte('=')
buf.WriteByte('"')
xml.Escape(buf, []byte(attr.Value))
buf.WriteByte('"')
}
}
}
}
if n.Document.EmptyElementTag {
if len(n.Children) == 0 && len(n.Text) == 0 {
buf.WriteString(" />")
if pretty {
buf.WriteByte('\n')
}
return
}
}
buf.WriteByte('>')
if len(n.Children) > 0 {
if pretty {
buf.WriteByte('\n')
}
for _, c := range n.Children {
p.printXML(buf, c, level+1, indent)
}
}
if len(n.Text) > 0 {
if n.Document.TextSafeMode {
xml.EscapeText(buf, []byte(n.Text))
} else {
buf.WriteString(n.Text)
}
}
if len(n.Children) > 0 && len(indent) > 0 {
buf.WriteString(strings.Repeat(indent, level))
}
buf.WriteString("</")
if space != nil {
buf.WriteString(space.Name.Local)
buf.WriteByte(':')
}
buf.WriteString(n.Name.Local)
buf.WriteByte('>')
if pretty {
buf.WriteByte('\n')
}
}