diff --git a/node.go b/node.go index 5972d05..e18df87 100644 --- a/node.go +++ b/node.go @@ -66,6 +66,15 @@ func (this *Node) GetValue() string { return res } +// SetValue sets the value of the node to the given parameter. +// It deletes all children of the node so the old data does not get back at node.GetValue +func (this *Node) SetValue(val string) { + t := NewNode(NT_TEXT) + t.Value = val + t.Parent = this + this.Children = []*Node{t} // brutally replace all other children +} + // Get node value as string func (this *Node) S(namespace, name string) string { foundNode := rec_SelectNode(this, namespace, name) diff --git a/xmlx_test.go b/xmlx_test.go index 1da420b..192aa20 100644 --- a/xmlx_test.go +++ b/xmlx_test.go @@ -4,7 +4,10 @@ package xmlx -import "testing" +import ( + "testing" + "encoding/xml" +) func TestLoadLocal(t *testing.T) { doc := New() @@ -251,3 +254,117 @@ func TestElementNodeValueFetch(t *testing.T) { t.Errorf("Failed to get availability using B, got: %v, wanted: true", v) } } + +// node.SetValue(x); x == node.GetValue +func TestElementNodeValueFetchAndSetIdentity (t *testing.T) { + // Setup: xyzzy + // The xmlx parser creates a nameless NT_TEXT node containing the value 'xyzzy' + rootN := NewNode(NT_ROOT) + rootN.Name = xml.Name{Space: "", Local: "root"} + textN := NewNode(NT_ELEMENT) + textN.Name = xml.Name{Space: "", Local: "text"} + namelessN := NewNode(NT_TEXT) + namelessN.Value = "xyzzy" + rootN.AddChild(textN) + textN.AddChild(namelessN) + + targetN := rootN.SelectNode("", "text") // selects textN + if (targetN != textN) { + t.Errorf("Failed to get the correct textN, got %#v", targetN) + } + + // targetN.Value is empty (as the value lives in the childNode) + if (targetN.Value != "") { + t.Errorf("Failed to prepare correctly, TargetN.Value is not empty, it contains %#v", targetN.Value) + } + + // Test correct retrieval + if v := rootN.S("", "text"); v != "xyzzy" { + t.Errorf("Failed to get value as string, got: '%s', wanted: 'xyzzy'", v) + } + + // Set the value of the nameless child + targetN.SetValue("plugh") + + // Test correct retrieval + if v := rootN.S("", "text"); v != "plugh" { + t.Errorf("Failed to get value as string, got: '%s', wanted: 'plugh'", v) + } +} + +// Test as it could be used to read in a XML file, change some values and write it out again. +// For example, a HTML/XML proxy service. +func TestElementNodeValueFetchAndSet(t *testing.T) { + IndentPrefix = "" + + data := ` + r + edBMW50 + .256 + 2 + + Tr + + ue` + doc := New() + + if err := doc.LoadString(data, nil); nil != err { + t.Fatalf("LoadString(): %s", err) + } + + carN := doc.SelectNode("", "car") + if carN == nil { + t.Fatalf("Failed to get the car, got nil, wanted Node{car}") + } + + colorNode := carN.SelectNode("", "color") + if colorNode == nil { + t.Fatalf("Failed to get the color, got nil, wanted Node{color}") + } + + colorVal := colorNode.GetValue() + if colorVal != "red" { + t.Fatalf("Failed to get the color, got %v, wanted 'red'", colorVal) + } + + colorNode.SetValue("blue") + + expected := `blueBMW50 + .256 + 2 + + Tr + + ue` + + + if got := doc.Root.String(); got != expected { + t.Fatalf("expected: \n%s\ngot: \n%s\n", expected, got) + } + + // now set the brand + brandNode := carN.SelectNode("", "brand") + if brandNode == nil { + t.Fatalf("Failed to get the color, got nil, wanted Node{brand}") + } + + brandVal := brandNode.GetValue() + if brandVal != "BMW" { + t.Fatalf("Failed to get the brand, got %v, wanted 'BMW'", brandVal) + } + + brandNode.SetValue("Trabant") + + // Notice, we lose the tag in BMW, that's intentional + expected = `blueTrabant50 + .256 + 2 + + Tr + + ue` + + if got := doc.Root.String(); got != expected { + t.Fatalf("expected: \n%s\ngot: \n%s\n", expected, got) + } +}