With my reasearch job at school I encountered a requirement to use XML files as input and ouput. The people who were going to use a snippit of our JAVA code are doing so from a C++ program. Since they are not programmers it was easier for them to call our code as a JAVA application than try to interface a JAVA library from within their C++ application. The decision was made that they would provide an XML file to invoke necissary options in my JAVA program and that I would return the results as an XML file.
Thus began my search to learn how to interface with XML files from JAVA code. Intially I found lots of acronymic libraries and APIs to do this work: JAXP, SAX, JDOM and another one I can't find at the moment. As I continued to look around, I found out that JAVA already has everything I need to work with XML files, at least with the small versions I had to work with. In the full post below I'll show some snippits of the XML files and the JAVA code that reads and writes them.
<?xml version="1.0" encoding="UTF-8"?>
<WorkpieceNeeded>
<Material>
<hasWeldability Value="High"/>
<hasToughness Value="High"/>
</Material>
<IntendedUse Value="FinishedPart"/>
<Shape Value="Cylinder"/>
</WorkpieceNeeded>
Above is the input XML file. It's relatively simple. It describes a desired workpiece that has a material, with some properties of materials, an intended use and a shape. This information is needed by my program which has a matchmaking algorithm to find workpieces that meet the requirements. So the first step is reading that XML file and grabbing the relevant details....
// Setup helper objects.
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// Read the file.
Document doc = docBuilder.parse(inFile);// Get the Material element
NodeList materialList = doc.getElementsByTagName("Material");
Node material = null;
if (materialList.getLength() == 1) {
material = materialList.item(0);
} else {
System.out.println("No material element was found in input file.");
return;
}
System.out.println("\t"+material.getNodeName());
// Get the property elements
NodeList nodeList = ((Element)material).getChildNodes();
for (int i=0; i < nodeList.getLength(); i++) {
Node property = nodeList.item(i);
if (property.getNodeName().equals("#text"))
continue;
NamedNodeMap propertyAttrib = property.getAttributes();
Node value = propertyAttrib.getNamedItem("Value");
System.out.println("\t\t"+property.getNodeName()+" has value "+value.getNodeValue());
}
FYI, I've left out the include statements (most are from the javax.xml and org.w3c.dom libraries which come with Sun Java). I've also taken out the try/catch blocks for the various exceptions that can pop-up. A quick run through of the code is I create some helper objects that will reference the XML document while it is in memory, then I read the actual XML file. I can then get any XML tag directly through the "getElementsByTagName()" method.
Since the Materials section of my XML file will have some unknown number of properties it is not efficent to get them individually by this same method. Instead, given the material 'node' I get all of the elements that are inside the tag using the "getChildNodes()" method. Then I iterate through the resulting array and grab each property element. When I was playing with the code, I was noticing that I was getting more than just the property tags using this method. I haven't delved too deeply into it because I was able to put in a quick fix. The extra elements in the list were composed of the name "#text"; so, I simply ignore them (the if ... continue statement in that block of code).
That shows the snippets to read the XML file and parse out the proerties and values. But how do we create the file? Here is that snippit of code:
// Setup helper objects.
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();// Create a new document.
Document doc = docBuilder.newDocument();
// Create the root of the document.
Element root = doc.createElement("WorkpieceNeeded");
// Create Material Node with its properties.
Node material = doc.createElement("Material");
Node weldable = doc.createElement("hasWeldability");
NamedNodeMap weldableAttributes = weldable.getAttributes();
Attr weldAttr = doc.createAttribute("Value");
weldAttr.setValue("High");
weldableAttributes.setNamedItem(weldAttr);
material.appendChild(weldable);
Node toughness = doc.createElement("hasToughness");
NamedNodeMap toughnessAttributes = toughness.getAttributes();
Attr toughAttr = doc.createAttribute("Value");
toughAttr.setValue("Medium");
toughnessAttributes.setNamedItem(toughAttr);
material.appendChild(toughness);
root.appendChild(material);
// Append root to the document
doc.appendChild(root);
// Transform the document
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
String xmlString = result.getWriter().toString();
// Spit out to the screen.
//System.out.println(xmlString);
// Write to a file.
Writer out = new OutputStreamWriter(new FileOutputStream(inFile));
out.write(xmlString);
out.close();
Once again I start off creating some helper objects. Then I start creating the elements and nodes that form the document with the "createElement()" method. I'll repeat a few lines of the code above to point out how to create XML tags with values specified in them:
Node weldable = doc.createElement("hasWeldability");
NamedNodeMap weldableAttributes = weldable.getAttributes();
Attr weldAttr = doc.createAttribute("Value");
weldAttr.setValue("High");
weldableAttributes.setNamedItem(weldAttr);
Once each element is completed, I attach it to its parent element with the "appendChild()" method. For example, the weldable node just above gets added: material.appendChild(weldable);. Once all the nodes have been created and added to the document, it goes through a transformation process that gives us a string representation of the document. That string can then be written out to the desired file.
In the end, reading and writing from an XML file and parsing its content was not that difficult a task. It didn't require any special APIs or libraries. And once you realize that the XML document is store in memory as a kind of graph it becomes fairly easy to figure out how to work with it. I was pleasantly surprised at the ease of this part of the project.
Comments
Nice work
Thank you for your message and i have known what should i do now.It helps me a lot~~Thank you very much~~ http://www.os-monitor.com/