diff --git a/pkg/util/xml.go b/pkg/util/xml.go
index aa52ee9..9eb5392 100644
--- a/pkg/util/xml.go
+++ b/pkg/util/xml.go
@@ -3,6 +3,7 @@ package util
import (
"encoding/xml"
"slices"
+ "sort"
"strings"
)
@@ -36,6 +37,9 @@ func NewXMLConfiguration() *XMLConfiguration {
func NewXMLConfigurationFromString(xmlData string) (*XMLConfiguration, error) {
config := &XMLConfiguration{}
+
+ xmlData = strings.TrimLeft(xmlData, " \t\n\r")
+
headerEnd := strings.Index(xmlData, "")
if headerEnd != -1 {
config.Header = xmlData[:headerEnd]
@@ -62,7 +66,7 @@ func (x *XMLConfiguration) GetProperty(name string) (Property, bool) {
return Property{}, false
}
-func (x *XMLConfiguration) AddProperty(p Property) {
+func (x *XMLConfiguration) addProperty(p Property) {
for i, existingProperty := range x.Configuration.Properties {
if existingProperty.Name == p.Name {
x.Configuration.Properties[i] = p // update
@@ -72,14 +76,27 @@ func (x *XMLConfiguration) AddProperty(p Property) {
x.Configuration.Properties = append(x.Configuration.Properties, p) // add
}
+func (x *XMLConfiguration) sort() {
+ sort.Slice(x.Configuration.Properties, func(i, j int) bool {
+ return x.Configuration.Properties[i].Name < x.Configuration.Properties[j].Name
+ })
+}
+
+func (x *XMLConfiguration) AddProperty(p Property) {
+ x.addProperty(p)
+ x.sort()
+}
+
func (x *XMLConfiguration) AddPropertyWithString(name, value, description string) {
x.AddProperty(Property{Name: name, Value: value, Description: description})
}
func (x *XMLConfiguration) AddPropertiesWithMap(properties map[string]string) {
for name, value := range properties {
- x.AddProperty(Property{Name: name, Value: value})
+ x.addProperty(Property{Name: name, Value: value})
}
+
+ x.sort()
}
func (x *XMLConfiguration) DeleteProperties(names ...string) {
@@ -102,6 +119,7 @@ func (x *XMLConfiguration) getHeader() string {
}
func (x *XMLConfiguration) Marshal() (string, error) {
+ x.sort()
data, err := xml.MarshalIndent(x.Configuration, "", " ")
if err != nil {
return "", err
diff --git a/pkg/util/xml_test.go b/pkg/util/xml_test.go
index e3fc6eb..ec7a9b5 100644
--- a/pkg/util/xml_test.go
+++ b/pkg/util/xml_test.go
@@ -1,6 +1,8 @@
package util
-import "testing"
+import (
+ "testing"
+)
func TestXMLConfiguration(t *testing.T) {
xmlData := `
@@ -43,8 +45,7 @@ func TestXMLConfiguration(t *testing.T) {
`
- expectedXMLData := `
-
+ expectedXMLData := `
+
+ hive.metastore.db.type
+ DERBY
+ Expects one of [derby, oracle, mysql, mssql, postgres]. Type of database used by the metastore. Information schema & JDBCStorageHandler depend on it.
+
hive.metastore.warehouse.dir
/user/hive/warehouse
@@ -76,11 +82,6 @@ func TestXMLConfiguration(t *testing.T) {
For example, jdbc:postgresql://myhost/db?ssl=true for postgres database.
-
- hive.metastore.db.type
- DERBY
- Expects one of [derby, oracle, mysql, mssql, postgres]. Type of database used by the metastore. Information schema & JDBCStorageHandler depend on it.
-
`
@@ -269,6 +270,14 @@ func TestXMLConfiguration_AddProperty(t *testing.T) {
if p.Value != "value1" {
t.Errorf("Property 'property1' has incorrect value. Expected: value1, Got: %s", p.Value)
}
+
+ property.Value = "value2"
+ config.AddProperty(property)
+
+ p, ok = config.GetProperty("property1")
+ if !ok {
+ t.Errorf("Expected property 'property1' not found")
+ }
}
func TestXMLConfiguration_DeleteProperties(t *testing.T) {
@@ -323,3 +332,38 @@ func TestXMLConfiguration_Marshal(t *testing.T) {
t.Errorf("Marshalled XML does not match expected XML. Expected:\n%s\nGot:\n%s", expectedXML, xmlData)
}
}
+
+func TestXMLConfiguration_Marshal_NoHeader(t *testing.T) {
+ xmlData := `
+
+
+ property1
+ value1
+
+
+`
+
+ expectedXML := `
+
+
+
+ property1
+ value1
+
+
+`
+
+ config, err := NewXMLConfigurationFromString(xmlData)
+ if err != nil {
+ t.Errorf("Failed to create XML configuration from string: %v", err)
+ }
+
+ xmlData, err = config.Marshal()
+ if err != nil {
+ t.Errorf("Failed to marshal XML configuration: %v", err)
+ }
+
+ if xmlData != expectedXML {
+ t.Errorf("Marshalled XML does not match expected XML. Expected:\n%s\nGot:\n%s", expectedXML, xmlData)
+ }
+}