Wednesday, July 3, 2013

Write and Read a XML in Maya with Python

It's been a while since the last post. I'm not in Andorra anymore... so I have been working on new stuff. In this case I bring to you 2 simple scripts to write and read a xml file in Maya using Python.

Some example uses:

  • Construct our game level on maya and import it to the game engine with the xml file. 
  • Copying animation poses.
  • Copying light settings.
  • ... 


Write the XML file:
from xml.dom.minidom import Document
import maya.cmds as cmds

doc = Document()

root_node = doc.createElement("scene")
doc.appendChild(root_node)

# Selection: 
# grab all selected objects
#selection = cmds.ls(sl=True)

# grab all visible objects, which type is transform
selection = cmds.ls(type="transform", v=True )

for object in selection:
    
    # create object element
    object_node = doc.createElement("object")
    root_node.appendChild(object_node)
    
    # BEWARE: after freeze transformations the translate is a bit tricky
    #object_translation = cmds.getAttr(object + ".translate")[0]
    object_translation = cmds.xform(object, query = True, worldSpace = True, rotatePivot = True) 
    
    # set attributes
    object_node.setAttribute("name", str(object))
    object_node.setAttribute("translateX", str(object_translation[0]))
    object_node.setAttribute("translateY", str(object_translation[1]))
    object_node.setAttribute("translateZ", str(object_translation[2]))
    

xml_file = open("C:/Temp/test.xml", "w")
xml_file.write(doc.toprettyxml())
xml_file.close()

print
print doc.toprettyxml()

Reading the XML file:
from xml.dom.minidom import parse

dom = parse("C:/Temp/test.xml")

 # visit every object node 
for node in dom.getElementsByTagName('object'): 
    
    # method 1: using keys
    attrs = node.attributes.keys()
    for a in attrs:
        pair = node.attributes[a]
        print (str(pair.name) + " = " + str(pair.value))
    print
    
    #method 2: by attribute name
"""        
    print str(node.getAttribute("name"))
    print str(node.getAttribute("translateX"))
    print str(node.getAttribute("translateY"))
    print str(node.getAttribute("translateZ"))
    print
"""

Based and inspired from Luiz Kruel's script

4 comments:

  1. Hello! How would I go about overwriting data? Say I just want to store the latest coordinates of an object. Right now I can only figure out how to append.

    Thanks!

    ReplyDelete
  2. Hello! How would I go about overwriting data? Say I just want to store the latest coordinates of an object. Right now I can only figure out how to append.

    Thanks!

    ReplyDelete
  3. @Mike Bourbeau. Any of the typical xml routines work in maya with a few snares here and there. Here are some XML docs: https://docs.python.org/2/library/xml.dom.html

    I think you'd want to use:

    node.replaceChild(newChild, oldChild)
    "Replace an existing node with a new node. It must be the case that oldChild is a child of this node; if not, ValueError is raised."

    ReplyDelete
  4. Hello Mike I just followed the tut, but get error when I try to read the file, any tip? Thx.
    Error: ExpatError: file D:\Program Files\Autodesk\Maya2019\bin\python27.zip\xml\dom\expatbuilder.py line 207: not well-formed (invalid token): line 2, column 11 #

    ReplyDelete