The XML Parser Xtra lets Director developers access the nodes of an XML document. A node can be a tag (similar to an HTML tag, also called an element), character data (text that does not appear inside the angle brackets of a tag), or a processing instruction (a special type of tag that passes data to the parsing application for special processing). You can extract information from the XML document by looking at its nodes with Lingo. This access to XML data lets users incorporate XML documents into their movies and selectively extract data from the documents.
An XML document is well formed if it has a coherent nesting structure and no misplaced angle brackets. Some XML documents can be associated with a document type declaration (DTD) file that describes specific rules for the XML tags the document uses. The XML parser of the Xtra checks that the XML follows the general rules of creating and using XML tags to ensure that the document is well formed. However, the Xtra does not check the DTD file to ensure that the tags follow the specific rules for XML document tags, which is described by the DTD. For this reason, the Xtra is called nonvalidating. The creator of the original XML document must follow the rules described in the DTD. Your Director movie should also include Lingo that checks for errors in the use of the XML document’s tags.
To use the XML Parser Xtra, create a parser object by using Lingo to assign a new instance of the Xtra to a variable. This variable now contains the parser object. Use a global variable if you need to access the XML data from anywhere in the Director movie.
global gParserObject
gParserObject = new(xtra "xmlparser")The next step is to parse the XML data using the parseString() command. The data can come from the text of a cast member or a string variable. To parse XML from a URL, use parseURL() instead. ParseString() and parseURL() return either VOID, which indicates that the command is successful, or an error code that indicates a problem with the XML data.
The following Lingo statement sets the variable errCode to the return value of the parseString() command:
errCode = gParserObject.parseString(member("XMLtext").text)After the XML Parser Xtra parses the data, the parser object contains all the data from the XML document.
The XML data can be considered a tree structure because most documents have tags nested within other tags, with each tag being like a branch of the tree.
The following example shows a short XML document:
<?xml version="1.0"?>
<e1><tagName attr1="val1" attr2="val2"/><e2>element 2</e2><e3>element 3</e3></e1>The following example is the same XML with its tree structure shown more clearly:
<?xml version="1.0"?>
<e1>
<tagName attr1="val1" attr2="val2"/>
<e2> element 2</e2>
<e3>element 3</e3>
</e1>There are two ways to access a parsed XML document. You can use the makeList() command to convert the document into a nested property list and use Lingo’s list-access commands, or you can use the special Lingo commands of XML Parser Xtra to access the parsed data directly.
The following Lingo statement uses the makeList() command to convert the parsed data to a property list:
theList = gParserObject.makeList()If you choose to make a property list with the makeList() command, the result is a nested property list, reflecting the tree structure of the XML.
Each element in the document is represented by its own property list, with another property list for each child element that it contains. The name of the element is the property name, and the content of the element is the property value. Attributes of an element are stored in a child list with the name !ATTRIBUTES. The property list of attributes contains the name of each attribute and its value. Character data has the property name !CHARDATA, and the value is the string representation of the character data. A processing instruction is a property with the name !PROCINST; its value is another two-element property list. The first property of this sublist is NAME, and the value is the string that represents the name of the processing instruction. The second property of the sublist has the name TEXT and contains the rest of the text in the processing instruction.
The property list resulting from the previous XML example would look like the following code:
["ROOT OF XML DOCUMENT": ["!ATTRIBUTES": [:], "e1": ["!ATTRIBUTES": [:], "tagName": ["!ATTRIBUTES": ["attr1": "val1", "attr2": "val2"]], "e2": ["!ATTRIBUTES": [:], "!CHARDATA": "element 2"], "e3": ["!ATTRIBUTES": [:], "!CHARDATA": "element 3"]]]]The following example is the same property list with its nested structure shown more clearly:
["ROOT OF XML DOCUMENT": ["!ATTRIBUTES": [:],
"e1": ["!ATTRIBUTES": [:],
"tagName": ["!ATTRIBUTES": ["attr1": "val1", "attr2": "val2"]],
"e2": ["!ATTRIBUTES": [:], "!CHARDATA": "element 2"],
"e3": ["!ATTRIBUTES": [:], "!CHARDATA": "element 3"]
]
]]Together, the Lingo statements that create a property list from a string of XML data would look like the following example:
global gParserObject
gParserObject = new(xtra "xmlparser")
errCode = gParserObject.parseString(member("XMLtext").text)
theList = gParserObject.makeList()After this code has been executed, the variable gParserObject contains the parsed node structure of the XML document, and the variable theList is a property list that contains all the information in the document broken into property name and value pairs. All the regular Lingo commands and functions for sorting and accessing lists can work normally with theList.