XPath and xml in maxscript for 3dsMax

When using xml in maxscript you need to be able to search the xml efficiently. I seem to use xml in all of my recent maxscripts. Especially in the latest online configurator I’m working on (still unreleased, expected later this year) all data is stored in xml. In this configurator there are a lot of options, so the xml is pretty big. This meant I needed some techniques to handle lots of xml. One of these techniques is: XPath.

XPath provides a fast and flexible system of looking through your xml-files. It’ll help you find the node or nodes you need quickly. This is also supported in maxScript. I learned a lot on the w3Schools site on xpath and other xml-related stuff. Let’s do a few examples:

I’ll use a sample xml from the w3Schools site (get it here)

<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
<book category="WEB">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>

Next up: some xpath queries which should function in maxscript

Put the xml above in a file called “bookstore.xml”
In maxscript enter the following lines

xmlDoc = dotNetObject "system.xml.xmlDocument"
xmlDoc.load @"somepathBookstore.xml"

This will load up the xml-file in the xmlDoc variable. Now we’re ready to do some xpath magic!

--1 Get all books
myNodes = xmlDoc.selectNodes "//book"
--2 Get all childnodes of the bookstore element
myNodes = xmlDoc.selectNodes "/bookstore/*"
--3 Get all authors of all books
myNodes = xmlDoc.selectNodes "//book/author"
--4 Get all authors of books from 2005
myNodes = xmlDoc.selectNodes "//book[year='2005']/author"
--4a do the same but the year is a variable 
yearVariable = 2005
myNodes = xmlDoc.selectNodes ("//book[year='" + (yearVariable as string) + "']/author")
--5 Get all books from 2005
myNodes = xmlDoc.selectNodes "//book[year='2005']"
--6 Get all books from 2003 cheaper than 45.00
myNodes = xmlDoc.selectNodes "//book[year='2003' and price<'45']"
 --In examples 3 and 4 you do something like this to get the actual text of the xml-element in an array
myAuthors = (for i = 0 to myNodes .count-1 collect myNodes .itemOf[i].innertext)
--In examples 1, 2, 5 and 6 you get an xml-element with child-elements. Do something like this to get a specific child-element
myPrices = (for i = 0 to myNodes.count-1 collect (myNodes.itemOf[i].getElementsByTagName "price").itemOf[0].innertext)

These examples are pretty simple and only use a fraction of what’s possible with xpath. However this is more than enough for my purposes and has helped me a lot in working with xml files. Example 4a also shows you can build up these xpath queries with variables. Don’t get confused with the single and double quotes!
Also check out the examples on the xpath documentation site.

For some real xml and maxscript kungfu check out Pete Addington’s site: http://lonerobot.net/
For a nice breakdown of xml in maxscript check out Paul Neale’s tutorials here and here.

Leave a Reply

* Will not be published