XmlDocument = Apollo.GetPackage("Drafto:Lib:XmlDocument-1.0").tPackage
XmlDocument is an XML manipulation library for Apollo. Its main purpose is to build Form documents purely from Lua, which can then be loaded as Windows in your Addon. This allows us to create arbitrary Windows on-the-fly, at run-time, without touching the file system. However, XmlDocument can also be used to create, modify, and serialize arbitrary XML documents.
XmlDocument can be thought of as a wrapper for Apollo's XmlDoc, but with massively extended functionality and a legitimate DOM API.
- Relationship to XmlDoc
- XmlDocument and XmlNode
- Create a Window
- Create an XML String
- Traverse a Document's Nodes
- API Reference
Chances are you've used XmlDoc already, because Houston will generate a call to one of its methods when you create a new Addon:
self.xmlDoc = XmlDoc.CreateFromFile("MyAddon.xml")
But what is XmlDoc? Very simply, it's Apollo's in-memory representation of an XML document. Here, the file "MyAddon.xml" is parsed and read into some C++ object, which is given to us as userdata. Take a look at one if you like, however you'll find its methods a bit cryptic. Many of them, such as AddLine()
, are meant for creating MLWindow markup rather than full-blown Forms. But XmlDocs can create Forms, so we find ourselves wanting methods like GetChildren()
and FindChild()
, similar to loaded Windows.
With a vanilla XmlDoc, the only solution is to convert the XmlDoc to a table using the ToTable()
method (or start from a new table), do your thing, then convert it back into an XmlDoc using XmlDoc.CreateFromTable()
. I won't dive into what this table looks like, because with XmlDocument you don't ever have to see it.
This library returns two objects - XmlDocument and XmlNode. An XmlDocument represents an entire XML file with a single root element. Each child element in the document is represented by an XmlNode.
XmlNodes can exist with or without a document, but we always create a node from an existing document using XmlDocument:NewNode()
. The node must still then be appended to an existing node in the document, or set as the root node.
-- Get XmlDocument from Apollo's Package system
local XmlDocument = Apollo.GetPackage("Drafto:Lib:XmlDocument-1.0").tPackage
-- Create a new Forms document
local tDoc = XmlDocument.NewForm()
-- Create a new Form for the document
local tForm = tDoc:NewFormNode("Form1", {
AnchorPoints = {0,0,0,0},
AnchorOffsets = {100,100,300,220},
Picture = true,
Sprite = "WhiteFill",
BGColor = "red",
Moveable = true
})
-- Add the new Form to the document root
tDoc:GetRoot():AddChild(tForm)
-- Load the Form as a Window
tDoc:LoadForm("Form1", nil, nil)
-- Create a new generic document
local xDoc = XmlDocument.New()
-- Set the root node
local html = xDoc:NewNode("html")
xDoc:SetRoot(html)
-- Add a child
local body = xDoc:NewNode("body")
html:AddChild(body)
-- Add another child
local div = xDoc:NewNode("div", {
class = "clickableDiv",
style = "width:100px; height:100px; background-color:#16C;",
onclick = "javascript:console.log('Hello');"
})
body:AddChild(div)
-- Serialize and Print
Print(xDoc:Serialize())
Coming soon...
This is the table returned by Apollo.GetPackage()
. It contains the factory methods for new documents, as well as wrapped versions of XmlDoc's factory methods. The returned XmlDocument object is described in the next section.
-
XmlDocument.New()
Returns a new XmlDocument. This document's root will be nil, so be sure to create a root node and call
SetRoot()
. -
XmlDocument.NewForm()
Returns a new Form XmlDocument. This is a special type of XmlDocument that has extra methods specific to Form XML, such as
LoadForm()
. It also comes with a root node, which is a<Forms>
element with no attributes. -
XmlDocument.CreateFromFile(strPath)
Similar to
XmlDoc.CreateFromFile()
, this parses the XML file atstrPath
and returns it as a new XmlDocument. -
XmlDocument.CreateFromTable(tXml)
Returns a new XmlDocument built from
tXml
.tXml
should be a table in the same format as the one returned byXmlDoc:ToTable()
, or the one given toXmlDoc.CreateFromTable()
.
The above factory methods return an object with the following API:
-
XmlDocument:GetRoot()
Returns the root XmlNode for this document.
-
XmlDocument:SetRoot(tNode)
Sets the root node of this document to XmlNode
tNode
. -
XmlDocument:NewNode(strTag, tAttributes)
Returns a new XmlNode for this document.
strTag
will be the tag name, andtAttributes
is a table of string key/value attribute pairs. Note that this method doesn't actually add the new node to the document; you must also append it to another node usingXmlNode:AddChild()
. -
XmlDocument:ToXmlDoc()
Returns an XmlDoc equivalent to this XmlDocument.
-
XmlDocument:ToTable()
Returns a table equivalent to this XmlDocument that can be passed to
XmlDoc.CreateFromTable()
. -
XmlDocument:Serialize()
Returns an XML string of this entire document, with indenting.
-
XmlDocument:NewFormNode(strName, tAttributes)
* Form documents only
Creates a new Form element for this document with Name
strName
. Note that this method doesn't actually add the new node to the document; you must also append it to another node usingXmlNode:AddChild()
. -
XmlDocument:NewControlNode(strName, strClass, tAttributes)
* Form documents only
Creates a new Control element for this document with Name
strName
and ClassstrClass
. Classes include "Window," "EditBox," "TabWindow," etc. Note that this method doesn't actually add the new node to the document; you must also append it to another node usingXmlNode:AddChild()
. -
XmlDocument:LoadForm(strName, wndParent, tHandler)
* Form documents only
Loads the Form with Name
strName
as a Window. This is equivalent toApollo.LoadForm()
.wndParent
is the parent Window, and can be nil for a top-level Window.tHandler
is the table used for event callbacks. There is currently a bug in Apollo where if tHandler is nil, events registered after loading the Window will fail to fire. So it's a good idea to always passself
as the 3rd argument.
An XmlNode is an object representing a single XML element, or node. XmlDocument:NewNode()
returns an XmlNode.
-
XmlNode:GetDocument()
Returns the owner XmlDocument of this node.
-
XmlNode:SetDocument(tDoc)
Sets the owner XmlDocument of this node. This relationship isn't enforced at all; it's simply for convenience.
-
XmlNode:GetChildren()
Returns an array of XmlNode children for this node.
-
XmlNode:AddChild(tNode)
Appends
tNode
to this node, and updates its owner document. -
XmlNode:RemoveChild(nId)
Removes and returns the child node at index
nId
. -
XmlNode:GetTag()
Returns the tag name of this node.
-
XmlNode:Attribute(strName, value)
Returns the value of attribute
strName
. Alternatively, ifvalue
is given, sets attributestrName
tovalue
.For Form documents, attributes should be identical to the Form XML files. There are also two special attributes,
AnchorPoints
andAnchorOffsets
, which can be given as a{left,top,right,bottom}
array form we've seen in other Apollo methods. -
XmlNode:Text(strText)
Returns the inner text of this node. Alternatively, if
strText
is given, sets the inner text tostrText
. -
XmlNode:Clone()
Returns a shallow copy of this node. Deep clone coming soon.
-
XmlNode:EachChild(fn)
Traverses each child of this node recursively, repeatedly calling
fn
with the current node as an argument. -
XmlNode:FindChild(fn)
Traverses each child of this node recursively, repeatedly calling
fn
with the current node as an argument. Iffn
returns true, the current node is returned. Otherwise traversal continues. -
XmlNode:FindChildByName(strName)
Returns the first node with a Name attribute equal to
strName
. -
XmlNode:ToTable()
Returns a table equivalent to this XmlNode (and all its children) that can be passed to
XmlDoc.CreateFromTable()
. -
XmlNode:Serialize()
Returns an XML string of this node (and all its children), with indenting.