99 lines
2.3 KiB
Swift
99 lines
2.3 KiB
Swift
|
import Foundation
|
||
|
|
||
|
struct XMLElement: Codable, CustomStringConvertible {
|
||
|
let name: String
|
||
|
let xmlns: String?
|
||
|
let attributes: [String: String]
|
||
|
let content: String?
|
||
|
let nodes: [XMLElement]
|
||
|
var woClose: Bool = false
|
||
|
|
||
|
var stringRepresentation: String {
|
||
|
var result = "<\(name)"
|
||
|
for (key, value) in attributes {
|
||
|
let val = value.escaped
|
||
|
result += " \(key)='\(val)'"
|
||
|
}
|
||
|
if let xmlns {
|
||
|
result += " xmlns='\(xmlns)'"
|
||
|
}
|
||
|
if !nodes.isEmpty {
|
||
|
result += ">"
|
||
|
for child in nodes {
|
||
|
result += child.stringRepresentation
|
||
|
}
|
||
|
result += "</\(name)>"
|
||
|
} else {
|
||
|
if let content = content {
|
||
|
result += ">"
|
||
|
result += content
|
||
|
result += "</\(name)>"
|
||
|
} else {
|
||
|
result += woClose ? ">" : "/>"
|
||
|
}
|
||
|
}
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
var description: String {
|
||
|
stringRepresentation.prettyStr
|
||
|
}
|
||
|
|
||
|
var data: Data {
|
||
|
Data(stringRepresentation.utf8)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// I decided to not use mutation functions and just
|
||
|
// make a new element during update
|
||
|
extension XMLElement {
|
||
|
func updateXmlns(_ new: String?) -> XMLElement {
|
||
|
XMLElement(
|
||
|
name: name,
|
||
|
xmlns: new,
|
||
|
attributes: attributes,
|
||
|
content: content,
|
||
|
nodes: nodes,
|
||
|
woClose: woClose
|
||
|
)
|
||
|
}
|
||
|
|
||
|
func addNode(_ new: XMLElement) -> XMLElement {
|
||
|
var nodes = nodes
|
||
|
nodes.append(new)
|
||
|
|
||
|
return XMLElement(
|
||
|
name: name,
|
||
|
xmlns: xmlns,
|
||
|
attributes: attributes,
|
||
|
content: content,
|
||
|
nodes: nodes,
|
||
|
woClose: woClose
|
||
|
)
|
||
|
}
|
||
|
|
||
|
func updateContent(_ new: String?) -> XMLElement {
|
||
|
guard let new else { return self }
|
||
|
|
||
|
var content = self.content ?? ""
|
||
|
content += new
|
||
|
|
||
|
return XMLElement(
|
||
|
name: name,
|
||
|
xmlns: xmlns,
|
||
|
attributes: attributes,
|
||
|
content: content,
|
||
|
nodes: nodes,
|
||
|
woClose: woClose
|
||
|
)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
extension XMLElement {
|
||
|
static var randomId: String {
|
||
|
let letters = "abcdefghijklmnopqrstuvwxyz0123456789"
|
||
|
return String((0 ..< 8).map { _ in letters.randomElement() ?? "x" })
|
||
|
}
|
||
|
}
|