Skip to content

Commit 67c6eff

Browse files
committed
Merge branch '#90'
2 parents dfdacba + d4f7469 commit 67c6eff

File tree

2 files changed

+137
-0
lines changed

2 files changed

+137
-0
lines changed

node.go

+49
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,55 @@ func AddAttr(n *Node, key, val string) {
172172
n.Attr = append(n.Attr, attr)
173173
}
174174

175+
// SetAttr allows an attribute value with the specified name to be changed.
176+
// If the attribute did not previously exist, it will be created.
177+
func (n *Node) SetAttr(key, value string) {
178+
if i := strings.Index(key, ":"); i > 0 {
179+
space := key[:i]
180+
local := key[i+1:]
181+
for idx := 0; idx < len(n.Attr); idx++ {
182+
if n.Attr[idx].Name.Space == space && n.Attr[idx].Name.Local == local {
183+
n.Attr[idx].Value = value
184+
return
185+
}
186+
}
187+
188+
AddAttr(n, key, value)
189+
} else {
190+
for idx := 0; idx < len(n.Attr); idx++ {
191+
if n.Attr[idx].Name.Local == key {
192+
n.Attr[idx].Value = value
193+
return
194+
}
195+
}
196+
197+
AddAttr(n, key, value)
198+
}
199+
}
200+
201+
// RemoveAttr removes the attribute with the specified name.
202+
func (n *Node) RemoveAttr(key string) {
203+
removeIdx := -1
204+
if i := strings.Index(key, ":"); i > 0 {
205+
space := key[:i]
206+
local := key[i+1:]
207+
for idx := 0; idx < len(n.Attr); idx++ {
208+
if n.Attr[idx].Name.Space == space && n.Attr[idx].Name.Local == local {
209+
removeIdx = idx
210+
}
211+
}
212+
} else {
213+
for idx := 0; idx < len(n.Attr); idx++ {
214+
if n.Attr[idx].Name.Local == key {
215+
removeIdx = idx
216+
}
217+
}
218+
}
219+
if removeIdx != -1 {
220+
n.Attr = append(n.Attr[:removeIdx], n.Attr[removeIdx+1:]...)
221+
}
222+
}
223+
175224
// AddChild adds a new node 'n' to a node 'parent' as its last child.
176225
func AddChild(parent, n *Node) {
177226
n.Parent = parent

node_test.go

+88
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,94 @@ func TestAddAttr(t *testing.T) {
147147
}
148148
}
149149

150+
func TestSetAttr(t *testing.T) {
151+
for _, test := range []struct {
152+
name string
153+
n *Node
154+
key string
155+
val string
156+
expected string
157+
}{
158+
{
159+
name: "node has no existing attr",
160+
n: &Node{Type: AttributeNode},
161+
key: "ns:k1",
162+
val: "v1",
163+
expected: `< ns:k1="v1"></>`,
164+
},
165+
{
166+
name: "node has an existing attr, overwriting",
167+
n: &Node{Type: AttributeNode, Attr: []Attr{{Name: xml.Name{Space: "ns", Local: "k1"}, Value: "v1"}}},
168+
key: "ns:k1",
169+
val: "v2",
170+
expected: `< ns:k1="v2"></>`,
171+
},
172+
{
173+
name: "node has no existing attr, no ns",
174+
n: &Node{Type: AttributeNode},
175+
key: "k1",
176+
val: "v1",
177+
expected: `< k1="v1"></>`,
178+
},
179+
{
180+
name: "node has an existing attr, no ns, overwriting",
181+
n: &Node{Type: AttributeNode, Attr: []Attr{{Name: xml.Name{Local: "k1"}, Value: "v1"}}},
182+
key: "k1",
183+
val: "v2",
184+
expected: `< k1="v2"></>`,
185+
},
186+
187+
} {
188+
189+
t.Run(test.name, func(t *testing.T) {
190+
test.n.SetAttr(test.key, test.val)
191+
testValue(t, test.n.OutputXML(true), test.expected)
192+
})
193+
}
194+
}
195+
196+
func TestRemoveAttr(t *testing.T) {
197+
for _, test := range []struct {
198+
name string
199+
n *Node
200+
key string
201+
expected string
202+
}{
203+
{
204+
name: "node has no existing attr",
205+
n: &Node{Type: AttributeNode},
206+
key: "ns:k1",
207+
expected: `<></>`,
208+
},
209+
{
210+
name: "node has an existing attr, overwriting",
211+
n: &Node{Type: AttributeNode, Attr: []Attr{{Name: xml.Name{Space: "ns", Local: "k1"}, Value: "v1"}}},
212+
key: "ns:k1",
213+
expected: `<></>`,
214+
},
215+
{
216+
name: "node has no existing attr, no ns",
217+
n: &Node{Type: AttributeNode},
218+
key: "k1",
219+
expected: `<></>`,
220+
},
221+
{
222+
name: "node has an existing attr, no ns, overwriting",
223+
n: &Node{Type: AttributeNode, Attr: []Attr{{Name: xml.Name{Local: "k1"}, Value: "v1"}}},
224+
key: "k1",
225+
expected: `<></>`,
226+
},
227+
228+
} {
229+
230+
t.Run(test.name, func(t *testing.T) {
231+
test.n.RemoveAttr(test.key)
232+
testValue(t, test.n.OutputXML(true), test.expected)
233+
})
234+
}
235+
}
236+
237+
150238
func TestRemoveFromTree(t *testing.T) {
151239
xml := `<?procinst?>
152240
<!--comment-->

0 commit comments

Comments
 (0)