-
Notifications
You must be signed in to change notification settings - Fork 25
/
createXpathInputs.go
126 lines (105 loc) · 3.13 KB
/
createXpathInputs.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
package main
import (
"encoding/xml"
"fmt"
"log"
"os"
"path/filepath"
"strings"
)
// XMLData represents XML data with XPath-like keys
type XMLData map[string][]string
func main() {
// Directory where XML files are located
dir := "user_config_files"
// Read the directory
files, err := os.ReadDir(dir)
if err != nil {
log.Fatal(err)
}
// Iterate through the files in the directory
for _, file := range files {
if file.IsDir() {
// Skip directories
continue
}
// Check if the file has a .xml extension
if filepath.Ext(file.Name()) == ".xml" {
// Open the XML file
xmlFile, err := os.Open(filepath.Join(dir, file.Name()))
if err != nil {
log.Fatal(err)
}
defer xmlFile.Close()
// Initialize a map to store XPaths
xpathMap := make(map[string]bool)
// Initialize an empty XMLData map
data := make(XMLData)
// Convert XML to XPaths and populate the XMLData map
getXPathsAndDataFromXML(xpathMap, data, xmlFile)
// Create Xpath Input file
createXpathInputsFile(xpathMap)
}
}
}
// Function traverses XML file, adds XPaths to the map, and stores XML data
func getXPathsAndDataFromXML(xpathMap map[string]bool, data XMLData, xmlFile *os.File) {
doc := xml.NewDecoder(xmlFile)
currentPath := []string{}
currentDataKey := []string{} // Keeps track of the current data key
// Start decoding the XML file
for {
t, err := doc.Token()
if err != nil {
break
}
switch se := t.(type) {
case xml.StartElement:
currentPath = append(currentPath, se.Name.Local)
xpath := strings.Join(currentPath, "/")
xpathMap[xpath] = true
// Append the XPath to the data map with an empty value
data[xpath] = append(data[xpath], "")
// Append the current element to the currentDataKey
currentDataKey = append(currentDataKey, se.Name.Local)
case xml.CharData:
// Get the text content and build the XPath-like key
content := strings.TrimSpace(string(se))
// fmt.Println(content)
if len(content) > 0 {
key := strings.Join(currentDataKey, "/")
content = content + ","
data[key] = append(data[key], content)
}
case xml.EndElement:
currentPath = currentPath[:len(currentPath)-1]
// Remove the last element from the currentDataKey
currentDataKey = currentDataKey[:len(currentDataKey)-1]
}
}
}
func createXpathInputsFile(xpathMap map[string]bool) {
// Part 2: Format and print XPaths directly
// Create a new file for formatted output
formattedXpathFile, err := os.Create("xpath_inputs.xml")
if err != nil {
log.Fatal(err)
}
defer formattedXpathFile.Close()
// Create an opening <file-list> tag
fmt.Fprintf(formattedXpathFile, "<file-list>\n")
// Iterate over the extracted XPaths and format them
for xpath := range xpathMap {
if strings.Contains(xpath, "/") {
// Format the line into XPath
formattedLine := fmt.Sprintf(" <xpath name=\"/%s\"/>\n", xpath)
// Write the formatted line to the output file
fmt.Fprintf(formattedXpathFile, formattedLine)
}
}
// Create a closing </file-list> tag
fmt.Fprintf(formattedXpathFile, "</file-list>\n")
fmt.Println()
fmt.Println("Xpath file written successfully in xpath_inputs.xml")
fmt.Println()
}