-
Notifications
You must be signed in to change notification settings - Fork 0
/
xml.go
132 lines (113 loc) · 2.74 KB
/
xml.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
122
123
124
125
126
127
128
129
130
131
132
package sitemap
// sitemap formatting with syntactic sugar. © Arthur Mingard 2022
import (
"encoding/xml"
"fmt"
)
const (
defaultVersion string = "1.0"
defaultEncoding string = "UTF-8"
defaultOutputPrefix string = ""
defaultOutputIndent string = " "
)
// XML is the top level XML node for the sitemap
type XML struct {
*parent `xml:",omitempty"`
sitemapIndex bool
pretty bool
outputPrefix string
outputIndent string
}
// applyXMLNS adds all required XML namespace values.
func (x *XML) applyXMLNS() {
var hasNews bool
var hasImage bool
var hasVideo bool
for _, l := range x.Locations {
if l.News != nil {
hasNews = true
}
if len(l.Images) > 0 {
hasImage = true
}
if len(l.Videos) > 0 {
hasVideo = true
}
}
if hasNews {
x.addXMLNS(XMLNSNews)
}
if hasImage {
x.addXMLNS(XMLNSImage)
}
if hasVideo {
x.addXMLNS(XMLNSVideo)
}
}
// Add inserts an entry into the XML's first parent node.
func (x *XML) Add(l *Location) {
if x.sitemapIndex {
l.isSitemapIndex()
}
x.parent.add(l)
}
// Output returns the output value as bytes
func (x *XML) Output() ([]byte, error) {
x.applyXMLNS()
out := []byte(x.headerString())
var err error
var marshalledXML []byte
if x.pretty {
marshalledXML, err = xml.MarshalIndent(x.parent, x.outputPrefix, x.outputIndent)
} else {
marshalledXML, err = xml.Marshal(x.parent)
}
if err == nil {
out = append(out, marshalledXML...)
}
return out, err
}
// PrettyFormat sets preferences for the prettified output.
func (x *XML) PrettyFormat(prefix, indent string) {
x.pretty = true
x.outputPrefix = prefix
x.outputIndent = indent
}
// OutputString returns the output as a string. Empty if there's an error.
func (x *XML) OutputString() (string, error) {
out, err := x.Output()
return string(out), err
}
// OutputPrettyString returns the output as a string with prettified rules. Empty if there's an error.
func (x *XML) OutputPrettyString(prefix, indent string) (string, error) {
x.PrettyFormat(prefix, indent)
return x.OutputString()
}
// headerString outputs the XML header string
func (x *XML) headerString() string {
xmlHeader := fmt.Sprintf(`<?xml version="%s" encoding="%s"?>`, defaultVersion, defaultEncoding)
if x.pretty {
return xmlHeader + "\n"
}
return xmlHeader
}
// defaultXML creates a default xml entity with required values.
func defaultXML() *XML {
return &XML{
outputPrefix: defaultOutputPrefix,
outputIndent: defaultOutputIndent,
}
}
// NewSitemapIndex creates a new sitemap with a sitemap_index child node.
func NewSitemapIndex() *XML {
out := New()
out.sitemapIndex = true
out.isSitemapIndex()
return out
}
// New returns a new instance of the default XML.
func New() *XML {
out := defaultXML()
out.parent = newParent()
return out
}