Thursday, November 6, 2008
XPath - Querying xml document
Core Java 5 introduced the package javax.xml.xpath, to enable querying and processing
xml documents in a robust manner.
(Note: it only works with DOM parser, and this may be a drawback in some cases)
In this tutorial, we are going to perform [select, insert, update and delete] in a given xml sample, using javax.xml.xpath.
Assume the following xml document structure, representing student/course relational model
<training>
<students>
<student id="18972" level="C" name="full name"/>
</students>
<courses>
<course id="01" level="C" name="Math"/>
<course id="02" level="B" name="MC"/>
<course id="03" level="A" name="Matlab"/>
<course id="04" level="A" name="Java"/>
</courses>
<student-course>
<registration courseId="01" studentid="18972"/>
</student-course>
</training>
Let's start coding:
- First, import classes we're going to use:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
- Then, we parse given xml & load it to memory:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse(xmlFile);
- We will instantiate javax.xml.xpath.XPath object to allow manipulating the previous document:
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer tFormer = tFactory.newTransformer();
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
- Assume we have a new student "Ahmad", passed exam with level "B",
thus we are going to register "Ahmad" to all level "B" courses.
Here, we'll add a new student element into <students> and new registration
element into <student-course>
// First, retrieve students element
NodeList nodes=dom.getElementsByTagName("students");
Node studentNDs=nodes.item(0);
// Add new student
Element child = dom.createElement("student");
String studentId=""+new Date().getTime();
child.setAttribute("name", "Ahmad");
child.setAttribute("id", studentId);
child.setAttribute("level", "B");
studentNDs.appendChild(child);
// Retrieve all courses assigned to level B, using xpath query
String xquery="//course[@level='B']";
XPathExpression expr = xpath.compile(xquery);
Object result = expr.evaluate(dom, XPathConstants.NODESET);
NodeList courseNDs = (NodeList) result;
// Add new resgistartion elements given retrieved courses ids, studentId:
NodeList relation=dom.getElementsByTagName("student-course");
for (int i = 0; i < courseNDs.getLength(); i++) {
Node nd=courseNDs.item(i);
String courseId=nd.getAttributes().getNamedItem("id").getNodeValue();
System.out.println("courseId "+courseId);
Element newRegistration= dom.createElement("registration");
newRegistration.setAttribute("studentid", studentId);
newRegistration.setAttribute("courseId", courseId);
relation.item(0).appendChild(newRegistration);
}
// Save changes to the Filesystem
DOMSource source = new DOMSource(dom);
tFormer.transform(source,new StreamResult(new FileOutputStream(xmlFile)));
- By the end of year, Ahmad's passed level B exams, and will upgrade to level A.
So, we're going to update Student Ahmad status, to level 'A',
and delete all previous courses registration assigned to Ahmad.
// retrieve Student Ahmad entry, given Id.
String xquery="//student[@id='"+id+"']";
XPathExpression expr = xpath.compile(xquery);
Object result = expr.evaluate(dom, XPathConstants.NODESET);
NodeList students = (NodeList) result;
Node studentND=students.item(0);
// modify 'level' attribute
String level="A";
studentND.getAttributes().getNamedItem("level").setNodeValue(level);
// Now, let's delete all registration entries, previously assigned to Ahmad
String xquery="//registration[@studentid='"+id+"']";
XPathExpression expr = xpath.compile(xquery);
Object result = expr.evaluate(dom, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
Node registerND=nodes.item(i);
// delete entry
registerND.getParentNode().removeChild(registerND);
}
// Save changes to filesystem
DOMSource source = new DOMSource(dom);
tFormer.transform(source,new StreamResult(new FileOutputStream(xmlFile)));
Labels:
Core Java
Subscribe to:
Post Comments (Atom)
2 comments:
Asallamo 3alykom
How are you Do3a', hope you doing well:)
I'm working on a web service project, I hope you help me with.
If you agree please contact me at this e-mail becoooool_1@yahoo.com
your sister,
UM_ABDULLAH
wa 3alikom essalam U.A.
You can post your questions/code snippets here.
Hope i can help you.
Post a Comment