package utils import ( "regexp" "strings" ) func EscapeInvalidXMLAttributeCharacters(xmlString string) string { // Regular expression to match content inside double quotes, but not the quotes themselves re := regexp.MustCompile(`"([^"]*?)"`) return re.ReplaceAllStringFunc(xmlString, func(attrValue string) string { // Extract the content inside the quotes (removing the enclosing quotes) content := attrValue[1 : len(attrValue)-1] // Escape the content inside the quotes escaped := strings.ReplaceAll(content, "&", "&") escaped = strings.ReplaceAll(escaped, "<", "<") escaped = strings.ReplaceAll(escaped, ">", ">") escaped = strings.ReplaceAll(escaped, `"`, """) escaped = strings.ReplaceAll(escaped, "'", "'") // Re-wrap the escaped content in quotes return `"` + escaped + `"` }) } func EscapeCdata(xmlString string) string { escaped := strings.ReplaceAll(xmlString, "]]>", "PDX_ESCAPED_CDATA_END") return escaped } func UnescapeCdata(xmlString string) string { escaped := strings.ReplaceAll(xmlString, "PDX_ESCAPED_CDATA_END", "]]>") return escaped } func StripCdata(xmlString, tagName string) string { openTag := "<" + tagName + ">" closeTag := "" xmlString = regexp.MustCompile(openTag+`\s*\s*`+closeTag).ReplaceAllString(xmlString, closeTag) return xmlString } func WrapCdata(xmlString, tagName string) string { openTag := "<" + tagName + ">" closeTag := "" xmlString = StripCdata(xmlString, tagName) xmlString = strings.ReplaceAll(xmlString, openTag, openTag+""+closeTag) return xmlString } func GetXMLTag(xmlString, tagName string, wrapCdata bool) string { openTag := "<" + tagName + ">" closeTag := "" // Get everything after the last opening tag split := strings.Split(xmlString, openTag) if len(split) < 2 { return "" } afterOpenTag := split[len(split)-1] // Get everything before the first closing tag split2 := strings.Split(afterOpenTag, closeTag) if len(split2) < 1 { return "" } processedXml := openTag + EscapeInvalidXMLAttributeCharacters(split2[0]) + closeTag if wrapCdata { processedXml = WrapCdata(processedXml, tagName) } return processedXml } func GetXMLContent(xmlString, tagName string) string { openTag := "<" + tagName + ">" closeTag := "" // Get everything after the last opening tag split := strings.Split(xmlString, openTag) if len(split) < 2 { return "" } afterOpenTag := split[len(split)-1] // Get everything before the first closing tag split2 := strings.Split(afterOpenTag, closeTag) if len(split2) < 1 { return "" } return split2[0] } // GetAllXMLContent returns all occurrences of content between the specified XML tags // as an array of strings. Returns an empty array if no matches are found. func GetAllXMLContent(xmlString, tagName string) []string { var results []string openTag := "<" + tagName + ">" closeTag := "" // Split by opening tag parts := strings.Split(xmlString, openTag) // Skip the first part (it's before any opening tag) for i := 1; i < len(parts); i++ { // Split by closing tag subParts := strings.Split(parts[i], closeTag) if len(subParts) > 0 { // The content is before the first closing tag results = append(results, subParts[0]) } } return results }