Xml in Nim
import xml, strformat
type
Plant = object
id: int
name: string
origin: seq[string]
proc `$`(p: Plant): string =
fmt"Plant id={p.id}, name={p.name}, origin={p.origin}"
proc main() =
var coffee = Plant(id: 27, name: "Coffee", origin: @["Ethiopia", "Brazil"])
# Emit XML representing our plant; using
# xmltree to produce a more human-readable output.
var node = newElement("plant")
node.attrs = {"id": $coffee.id}.toXmlAttributes
node.add newElement("name")
node.child("name").add newText(coffee.name)
for place in coffee.origin:
node.add newElement("origin")
node.child("origin")[^1].add newText(place)
echo node
# To add a generic XML header to the output, append
# it explicitly.
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", node
# Use parseXml to parse a string with XML
# into a data structure. If the XML is malformed or
# cannot be mapped onto Plant, a descriptive error
# will be raised.
let xmlString = $node
var parsed = parseXml(xmlString)
var p = Plant(
id: parseInt(parsed.attr("id")),
name: parsed.child("name").innerText,
origin: @[]
)
for originNode in parsed.findAll("origin"):
p.origin.add originNode.innerText
echo p
var tomato = Plant(id: 81, name: "Tomato", origin: @["Mexico", "California"])
# The parent>child>plant structure can be created
# using nested XML elements
var nesting = newElement("nesting")
var parent = newElement("parent")
var child = newElement("child")
for plant in @[coffee, tomato]:
var plantNode = newElement("plant")
plantNode.attrs = {"id": $plant.id}.toXmlAttributes
plantNode.add newElement("name")
plantNode.child("name").add newText(plant.name)
for place in plant.origin:
plantNode.add newElement("origin")
plantNode.child("origin")[^1].add newText(place)
child.add plantNode
parent.add child
nesting.add parent
echo nesting
main()
This Nim code demonstrates XML processing capabilities similar to the original example. Here’s a breakdown of the changes and explanations:
We import the
xml
module for XML processing andstrformat
for string formatting.The
Plant
type is defined as an object in Nim, which is similar to a struct in other languages.The
$
operator is overloaded to provide a string representation of thePlant
object.In the
main
procedure, we create XML nodes using thenewElement
andnewText
functions from thexml
module.To parse XML, we use the
parseXml
function, which returns anXmlNode
. We then extract the data from this node to create aPlant
object.The nested XML structure is created by manually constructing nested
XmlNode
objects.Error handling in Nim is typically done through exceptions, which would be raised automatically if there are issues with XML parsing or other operations.
This Nim code provides similar functionality to the original example, allowing for XML creation, parsing, and manipulation. The syntax and some concepts are different, but the overall structure and flow of the program remain similar.