I’ve had a lot of comments in the past few months about MATLAB’s XML functionality, so I guess it’s time to provide a few more posts on the matter. Today is part 4 of the series, this time covering some of the limitations of xmlwrite.
XMLWRITE is MATLAB’s function for serializing the document element. With just one argument, the xml content is printed to the Command Window. With two arguments that data is saved to a text file. This function doesn’t give you a lot of room to customize the output; we pretty much expect that most MATLAB users will want the default. However, there are times when you’ll need a little extra control over the output. The advanced concept here is that although you create an XML document object in the MATLAB workspace, the output is really controlled by a Java serializer object, and does not use all of the document’s properties. XMLWRITE creates and executes the serializer for you. To customize this process you’ll have to manage the serialization yourself using MATLAB’s Java interface.
In particular, the properties set on the XML node in the output file are set by the serializer and not the DOM object passed to XMLWRITE. This limitation was encountered by some of my blog’s commenters and users of MATLAB Answers. For an example, see this MATLAB Answers post: “setXmlStandalone bug?.” The workaround I presented in that post, I’ve duplicated below. Fair warning, this is an advanced Java maneuver.
docNode = com.mathworks.xml.XMLUtils.createDocument('AddressBook'); docNode.getDocumentElement.appendChild(docNode.createElement('b')); docNode.getDocumentElement.appendChild(docNode.createElement('a')); %don't do this docNode.setXmlStandalone(1) import javax.xml.transform.*; import javax.xml.transform.dom.*; import javax.xml.transform.stream.*; tfactory = TransformerFactory.newInstance; transformer = tfactory.newTransformer; src = DOMSource(docNode); stream = java.io.StringWriter; dst = StreamResult(stream); %set the value here instead transformer.setOutputProperty(OutputKeys.STANDALONE,'yes'); transformer.setOutputProperty(OutputKeys.VERSION,'1.1'); transformer.setOutputProperty(OutputKeys.ENCODING,'ASCII'); transformer.transform(src,dst); result = char(stream.toString)
result = <?xml version="1.1" encoding="ASCII" standalone="yes"?><AddressBook><b/><a/></AddressBook>
As you can see, from this code, setting the OutputProperty using OutputKeys allows us to control what shows up in the final XML document. Properties set on docNode are ignored. In this example I use a StringWriter to get a String form of the XML, but you can use a FileWriter to save it to disk.
I’ve received some comments that this solution is not the friendly MATLAB code we’re used to, so I’ve created enhancement requests to bring some of this functionality into XMLWRITE.
Other posts in the series:
EDIT 2/21/2012: updated javadoc links