This plugin wraps the XML parsing library by Frank Vanden Berghen. The source code for it can be downloaded from this location:
http://iridia.ulb.ac.be/~fvandenb/tools/xmlParser.html.
All commands have help implemented. This help can be accessed by tying the command with the '-h' flag or by using the Maya help system (type 'help commandname').
Any bugs, questions, comments should be reported to: w.david.lewis@gmail.com.
If you're already familiar with XML, you can skip to the next section.
<?xml version="1.0"
encoding="utf-8"?>
<element
attr1 = "value">
Data item 1
Data item 2
<childelement>
</childelement>
</element>
In this example XML, you can see all the all the basic pieces in an XML file.
The first line '<?xml version="1.0" encoding="utf-8"?>' is the declaration element. It describes the file as XML and tells the XML version and the encoding. This version of the XML plugin will always use utf-8 as the encoding.
<element> is an XML element. It has one attribute called 'attr1'. The value of this attribute is 'value'. The element also contains two data items and one child element (called 'childelement'). There can be multiple child elements. Data elements and child elements can be intermixed. Child elements can have attributes of their own and have zero or more child elements and data items. Child elements are just elements.
For a detailed description of XML, please see:
http://www.w3.org/TR/2000/REC-xml-20001006
Rightly or wrongly, in the following documentation I will use the terms XML element and XML node synonymously.
Since we can't add new types in MEL, we must have a way to deal with XML elements. This plugin uses a mechanism similar to what the 'fopen' MEL command does for files. 'fopen' returns an integer that represents the file you are reading from or writing to. You perform operations on the file and then close it when you're done.
Using this plugin, XML element nodes are represented by a handle; this handle is an integer. You manipulate a node by getting access to the handle for that node and performing operations on it. You can't manipulate a node without first getting the handle to it.
You start with the top-level node and navigate down by querying the node for its children. You can also query a node for its attributes and its data items.
XML that has been loaded is referred to as an XML document. You can have multiple XML documents open at once.
This library is pretty forgiving in the XML that it will read. It will read XML with or without an XML declaration node. It will read XML that is wrapped in a containing XML node or just a group of nodes.
This is an example of XML that contains a declaration node.
<?xml version="1.0"
encoding="utf-8"?>
<element_a>
<element_b1/>
<element_b2>
<element_c1/>
<element_c2/>
</element_b2>
<element_b3/>
</element_a>
When this XML is parsed by xmlFromFile or xmlFromString, a handle to the declaration node is returned. The top-level containing node ("element_a1" in this case) is the first and only child element of the declaration element.
Here is an example XML that has a single XML element the top-level.
<element_a>
<element_b1/>
<element_b2>
<element_c1/>
<element_c2/>
</element_b2>
<element_b3/>
</element_a>
When this XML is parsed by xmlFromFile or xmlFromString, a handle is returned to the containing XML element ('element_a'). This element will have three children, one corresponding to element_b1, element_b2 and element_b3.
Here is an example XML that has no single top-level element that contains everything else.
<element_a1>
<element_b1/>
<element_b2/>
</element_a1>
<element_a2>
<element_b1/>
<element_b2/>
</element_a2>
<element_a3>
<element_b1/>
<element_b2/>
</element_a3>
When this XML is parsed by xmlFromFile or xmlFromString, a handle is returned to a fictitious top XML element called '$/'. In the above example, the handle is returned to '$/', and it has three child elements: 'element_a1', 'element_a2' and 'element_a3'.
The '$/' is not written out by the xmlToFile or the xmlToString command. If you load the XML example above and then write it back out, you should get the same XML you started with.
Just like you can have multiple files open at once, you can have multiple XML documents open a once.
This plugin provides 8 commands.
There are four commands for loading and saving XML. Two are for reading to/from a string and two
for reading to/from a file. All commands
that load XML return an integer handle to the top-level element in the XML.
There is a fifth command for releasing the loaded XML when
you’re done reading it.
There are three commands for manipulating the XML document once it’s been loaded.
usage: int $handle = `xmlFromFile filename`;
Flags:
xmlFromFile has no flags
This command returns a handle to the top-level node in the specified XML file. The top-level node can be a declaration node, an XML node or the fictitious '$/' node.
usage: int $handle = `xmlFromString "xmlstring"`;
Flags:
xmlFromString has no flags
This command returns a handle to the top-level node in the specified XML file. The top-level node can be a declaration node, an XML node or the fictitious '$/' node.
usage: xmlToFile [flags] handle filename
Flags:
|
-f, -format |
formats the XML to be more human readable |
|
-dec, -declaration |
writes a declaration node to the XML |
handle is the handle to the XML node to save to a file. This handle can be for a top-level element or an element in the middle of the tree.
filename is the filename to write the XML to.
usage: string $s = `xmlToString [flags] handle`;
Flags:
|
-f, -format |
formats the XML to be more human readable. |
handle is the handle to the XML element to convert to a string. This handle can be for a top-level element or an element in the middle of a tree.
Usage: xmlReleaseDocument handle;
Flags: none
Releases all the memory used by an XML document and all of its children. This will invalidate all the handles from any children that you have acquired.
handle is the handle to the top-level XML node. This command will only work with top-level nodes (the declaration node, the containing XML element or the fictitious ‘$/’ element).
Used for querying an XML element about its child elements and create new XML elements. Can also delete child nodes, delete attributes and delete data items.
Usage: xmlElement [flags] handle;
Return value depends on the combination of flags being passed
Supports query mode, edit mode, and create mode.
Flags:
|
Flag |
Description |
Mode |
|
-e, -edit |
places the command in edit mode |
|
|
-q, -query |
places the command in query mode |
|
|
-r, -remove |
removes the specified sub-part of the element (attribute, data, or child node) [e] |
|
|
-a, -attribute |
operation is performed on an attribute of the xml element |
[e] [q] |
|
-c, -child |
operation is performed on a child element of the xml element |
[c] [e] [q] |
|
-dt, -data |
operation is performed on a data item of the xml element |
[e] [q] |
|
-dec, -declaration |
whether the element is a declaration |
[q] |
|
-i, -index |
specifies the sub-part by index |
[c] [e] [q] |
|
-n, -name |
specifies the sub-part by name |
[c] [e] [q] |
For the purposes of this command, a sub-part of an element is an attribute, a child, or a data item. Sub-parts may be specified by name or by index. In general, either the name or the index may be specified but not both. If there are multiple sub-parts of the same type with the same name (which is perfectly legal XML), the sub-parts must be accessed by index rather than by name. If accessed by name, in general, only the first of those sub-parts will be acted upon which is generally not what you want. Indices are zero-based (e.g. the first element is index 0).
In general, querying for a child, attribute or data item without specifying the sub-part by name or index will return the count of the sub-parts.
int $h = `xmlFromString "<?xml version="1.0"
encoding="utf-8"?><element_a />"`;
int $isDeclaration = `xmlElement -q -dec $h`;
In this example, $isDeclaration will be true (equal to one) since the top-level node is a declaration node.
int $h = `xmlFromString
"<element_a attr1="one"
attr2='two'/>"`;
int $attributeCount = `xmlElement -q -attribute $h`;
In this example $attributeCount will contain the number of attributes on the XML element (in this case, 2).
int $h = `xmlFromString
"<element_a>Data
1\nData2\n</element_a>"`;
int $dataCount = `xmlElement -q -data $h`;
In this example, $dataCount will contain the number of data items in the XML (which will be two in this case).
int $h = `xmlFromString
"<element_a><child1 /><child2
/></element_a>"`;
int $childCount = `xmlElement -q -child $h`;
This example queries a node for the number of child elements it contains. $childCount will contain the number of child elements underneath the top-level element (in this case, two).
These are examples of querying an XML element for a child element.
int $h = `xmlFromString
"<element_a><child1 /><child2
/></element_a>"`;
int $childHandle = `xmlElement -q -child -index 1 $h`;
This example querys for a child XML element by index. In this case, $childHandle will contain the handle to the second child (the <child2 /> element) since indices are zero-based.
int $h = `xmlFromString
"<element_a><child1 /><child2
/></element_a>"`;
int $childHandle = `xmlElement -q -child -name "child1" $h`;
This example queries for a child XML element by name. In this case, $childElement will contain the handle to the first child element of <element_a> (the <child1 /> element).
int $h = `xmlFromString
"<element_a><child1 /><child2
/></element_a>"`;
int $childHandle =
`xmlElement -q -child -name "child1" $h`;
int $rootParent = `xmlElement -q -parent $h`;
int $childParent =
`xmlElement -q -parent $childHandle`;
This example queries for the parent of the root node and the parent of the child. In this case, $rootParent will be equal to -1 (the parent of a top-level node will be -1) and $childParent will be equal to $h.
int $h = `xmlFromString
"<element_a><child1 /><child2
/></element_a>"`;
int $childHandle = `xmlElement -child -name "child3" $h`;
If the index flag isn't present when creating a new element, the new element will go at the end of the existing elements. If an index is provided, the new element will be inserted after that point. A value of ‘-1’ will insert at the beginning of the list of children.
int $h = `xmlElement
-child -name "top" -1`;
This example will create a new top-level XML element. Specifying a -1 as the parent indicates the element should be a top-level element. The new document should be destroyed with xmlReleaseDocument when you're done with it.
int $h = `xmlFromString
"<element_a><child1 /><child2
/></element_a>"`;
xmlElement -e -name "top" $h;
This command changes the name of the top XML element from "element_a" to "top".
int $h = `xmlFromString
"<element_a><child1 /><child2
/></element_a>"`;
xmlElement -e -remove -child -index 0 $h;
This example deletes the child at index position zero ("child1"). The child can be specified by name or by index.
int $h = `xmlFromString
"<element_a attr1="one"
attr2='two'/>"`;
xmlElement -e -remove -attribute -index 0 $h;
This example deletes the attribute at index position zero ("attr1"). The attribute can be specified by name or by index.
int $h = `xmlFromString
"<element_a>Data
1\nData2\n</element_a>"`;
xmlElement -e -remove -data -index 0 $h;
This example deletes the data item at index position zero ("Data 1"). The data can be specified by name or by index.
The 'xmlAttribute' command is used to query the name, value and index position of an attribute. It can also be used to edit the name and value of an attribute and add new attributes to an XML element.
Usage: xmlAttribute [flags] handle;
Return value depends on the combination of flags being passed
Supports query mode, edit mode, and create mode.
Flags:
|
Flag |
Description |
Mode |
|
-e, -edit |
places the command in edit mode |
|
|
-q, -query |
places the command in query mode |
|
|
-i, -index |
specifies the attribute by index |
[c] [e] [q] |
|
-n, -name |
specifies the attribute by name |
[c] [e] [q] |
|
-v, -value |
specifies the value of the attribute |
[c] [e] |
int $h = `xmlFromString
"<element_a attr1="one"
attr2='two'/>"`;
string $attributeName = `xmlAttribute -q -index 0 -name $h`;
This example returns the name of the attribute at index position zero. When querying an attribute name, it must be specified by name.
int $h = `xmlFromString
"<element_a attr1="one"
attr2='two'/>"`;
string $attributeName = `xmlAttribute -q -index 0 -value $h`;
This example returns the value of the attribute at index position zero. The attribute can be specified by index or by name.
int $h = `xmlFromString
"<element_a attr1="one"
attr2='two'/>"`;
int $attributeIndex = `xmlAttribute -q -name "attr1" -index $h`;
This example returns the index of the attribute named "attr1". When querying the index of an attribute it must be specified by name.
int $h = `xmlFromString
"<element_a attr1="one"
attr2='two'/>"`;
xmlAttribute -e -name "attr1" -value "new value $h`;
This example changes the value of the attribute named "attr1" from "one" to "new value". When editing the value of an attribute, it may be specified by index or by name.
int $h = `xmlFromString
"<element_a attr1="one"
attr2='two'/>"`;
xmlAttribute -e -index -name "new name" $h`;
This example changes the name of the attribute named "attr1" from "attr1" to "new name". When editing the name of an attribute, it must be specified by index.
int $h = `xmlFromString
"<element_a attr1="one"
attr2='two'/>"`;
xmlAttribute -name "attr3" -value "three" $h`;
This example adds a new attribute name "attr3" with a value of "three" to the XML node.
The 'xmlData' command is used to query the value of an attribute. It can also be used to edit the value of a data item and add new data items to an XML element.
Usage: xmlData [flags] handle;
Return value depends on the combination of flags being passed
Supports query mode, edit mode, and create mode.
Flags:
|
-e, -edit |
places the command in edit mode |
|
|
-q, -query |
places the command in query mode |
|
|
-i, -index |
specifies the data by index |
[c] [e] [q] |
|
-v, -value |
specifies the value of the attribute |
[c] [e] [q] |
int $h = `xmlFromString
"<element_a>Data
item</element_a>"`;
string $dataValue = `xmlAttribute -q -index 0 $h`;
This example queries the value of the first data item and returns it. Data items must be specified by index.
int $h = `xmlFromString
"<element_a>Data
item</element_a>"`;
string $dataValue = `xmlAttribute -e -index 0 -value "New Data" $h`;
This example edits the value of the first data item and changes it from "Data item" to "New Data". Data items must be specified by index.
int $h = `xmlFromString
"<element_a>Data
item</element_a>"`;
string $dataValue = `xmlAttribute -index 0 -value "New Data" $h`;
This example creates a new data item. The location of the new item may be specified by index. If the index flag is not set, then the new data item is added to the end of the data items.