XML

"Continuous effort - not strength or intelligence - is the key to unlocking our potential." ==> Winston Churchill

Name:
Location: Bangalore, India

Sunday, February 17, 2008

Accessing an XML document to retrieve attribute values

Requirement:

We have an XML file with a element and couple of attributes in it. We need to parse the XML file and retrieve only the attribute values.

XML File (ABCSQLQueries):

<ABCQUERIES
TBUUSLIST_QUERY="SELECT TBUISUSKEY,TBUISUSNAME FROM OWN_ABC.TBUISUSLABELS"
AVAILABLEWITH_QUERY="SELECT A.REQUESTAVAILABLEKEY, A.DISPLAY FROM OWN_ABC.REQUESTAVAILABLE A, OWN_ABC.REQUESTDETAILS
B WHERE B.REQUESTDETAILSKEY = ? AND A.REQUESTAVAILABLEKEY = B.REQUESTAVAILABLEKEY"
/>

Code:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Attr;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.DOMException;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;


public class XmlReading {

Document doc;
Element element;
private static String fileName = "ABCSQLQueries.xml";

public static void main(String[] args) {
XmlReading xr = new XmlReading();
// xr.getXmlParser();
xr.getXmlParser(args);
}


public void getXmlParser() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

try {
DocumentBuilder builder = factory.newDocumentBuilder();
InputStream objInputStream = this.getClass().getResourceAsStream(fileName);
doc = builder.parse(objInputStream);
}catch(ParserConfigurationException parserException) {
}catch(SAXException saxException) {
}catch(IOException ioException) {
}catch(Exception exception){}

getAttributes();
}


public void getXmlParser(String[] args) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

if(args.length != 1) {
System.err.println("XML File Required");
}

try {
DocumentBuilder builder = factory.newDocumentBuilder();
doc = builder.parse(new File(args[0]));
}catch(ParserConfigurationException e1) {
}catch(SAXException e2) {
}catch(IOException e3) {
}
getAttributes();
}

public void getAttributes() {

// Retrive the entire Document from the Dom Tree
element = doc.getDocumentElement();
// Retrive the attribute list from document
NamedNodeMap attrs = element.getAttributes();

// Get number of attributes in the element
int numAttrs = attrs.getLength();
System.out.println("\n Number of Attribute: " + numAttrs + "\n");

// Process each attribute

for (int i=0; i<numAttrs; i++) {
Node node = attrs.item(i);
// Get attribute name and value
String attrName = node.getNodeName();
String attrValue = node.getNodeValue();
System.out.println("Attribute Name: " + attrName + "\nAttribute Value: " + attrValue + "\n");
}

}
}

XML parsing has been done in both ways like user can give the XML file as input through console as well as hard-code the XML file name directly in the parsing java file.

Accessing an XML document to retrieve element values

Requirement:

We have an XML file with couple of elements wrapped in a parent element. We need to parse the XML file and retrieve only the child element values.

XML File (ABCSQLQueries):

<ABCQUERIES>
<TBUUSLIST_QUERY>
SELECT TBUISUSKEY,TBUISUSNAME FROM OWN_ABC.TBUISUSLABELS
</TBUUSLIST_QUERY>
<AVAILABLEWITH_QUERY>
SELECT A.REQUESTAVAILABLEKEY, A.DISPLAY FROM OWN_ ABC.REQUESTAVAILABLE A, OWN_ ABC.REQUESTDETAILS B WHERE B.REQUESTDETAILSKEY = ? AND A.REQUESTAVAILABLEKEY = B.REQUESTAVAILABLEKEY
</AVAILABLEWITH_QUERY>
</ABCQUERIES>

Code:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Attr;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.DOMException;

import org.xml.sax.SAXException;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

public class XmlReading {

Document doc;
Element element;
private static String fileName = "ABCSQLQueries.xml";


public static void main(String[] args) {
XmlReading xr = new XmlReading();
xr.getXmlParser();
// xr.getXmlParser(args);
}

public void getXmlParser() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

try {
DocumentBuilder builder = factory.newDocumentBuilder();
InputStream objInputStream = this.getClass().getResourceAsStream(fileName);
doc = builder.parse(objInputStream);
}catch(ParserConfigurationException parserException) {
}catch(SAXException saxException) {
}catch(IOException ioException) {
}catch(Exception exception){}

getAttributes();
}

public void getXmlParser(String[] args) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

if(args.length != 1) {
System.err.println("XML File Required");
}

try {
DocumentBuilder builder = factory.newDocumentBuilder();
doc = builder.parse(new File(args[0]));
}catch(ParserConfigurationException e1) {
}catch(SAXException e2) {
}catch(IOException e3) {
}
getAttributes();
}

public void getAttributes() {

// Retrive the entire Document from the Dom Tree
element = doc.getDocumentElement();
String s1 = element.getTagName();
System.out.println("\nRoot Tag Name: " + s1);

// To get all the elements in a DOM Tree
NodeList nl1 = element.getElementsByTagName("*");
int i2 = nl1.getLength();
System.out.println("No of Elements: " + i2 + "\n");
for(int i=0; i<i2; i++) {
Node node = nl1.item(i);

System.out.println("Node Name: " + node.getNodeName());
System.out.println("Node Value: " + node.getFirstChild().getNodeValue());
}

}
}

XML parsing has been done in both ways like user can give the XML file as input through console as well as hard-code the XML file name directly in the parsing java file.

Accessing an XML document using DOM

Requirement:
We have a completely organized XML file with SQL Queries. We need to parse the XML file and retrieve only the SQL Queries based on module code and sql query id.


XML File (ABCSQLQueries):


<SQL_ROOT>
<MODULE CODE="REQUEST">
<SQL_SEQMENT ID="PAYMENTTERMS_QUERY">
SELECT A.PAYMENTTERMSKEY, A.DISPLAY FROM OWN_ABC.PAYMENTTERMS A, OWN_ABC.REQUESTDETAILS B WHERE
B.REQUESTDETAILSKEY = ? AND A.PAYMENTTERMSKEY = B.PAYMENTTERMSKEY
</SQL_SEQMENT>
<SQL_SEQMENT ID="REQUEST_UPDATE">
update request query
</SQL_SEQMENT>
</MODULE>
<MODULE CODE="BANK">
<SQL_SEQMENT ID="BANK_SELECT">
Select bank query
</SQL_SEQMENT>
<SQL_SEQMENT ID="BANK_UPDATE">
update bank query
</SQL_SEQMENT>
</MODULE>
<MODULE CODE="COUNTRY">
<SQL_SEQMENT ID="COUNTRY_SELECT">
Select country query
</SQL_SEQMENT>
<SQL_SEQMENT ID="COUNTRY_UPDATE">
update country query
</SQL_SEQMENT>
</MODULE>
</SQL_ROOT>

Code:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Attr;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.DOMException;

import org.xml.sax.SAXException;

import java.io.InputStream;
import java.io.IOException;

public class XMLParsing {

static Document doc;
static Element element;
private static String fileName = "ABCSQLQueries.xml";

public static void main(String[] args) {
XMLParsing xr = new XMLParsing();
xr.getXmlParser();
}

public void getXmlParser() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

try {
DocumentBuilder builder = factory.newDocumentBuilder();
InputStream is = this.getClass().getResourceAsStream(fileName);
doc = builder.parse(is);
}catch(ParserConfigurationException parserException) {
}catch(SAXException saxException) {
}catch(IOException ioException) {
}catch(Exception exception){}
getElements("REQUEST", "PAYMENTTERMS_QUERY");
}

public static String getElements(String moduleName, String queryName) {

String gtemQuery = null;
// Retrive the entire Document from the Dom Tree
element = doc.getDocumentElement();
String s1 = element.getTagName();
System.out.println("\nRoot Tag Name: " + s1);

NodeList parentNodeList = element.getElementsByTagName("MODULE");

for(int parentNode = 0; parentNode < parentNodeList.getLength(); parentNode++) {
Node queryNode = parentNodeList.item(parentNode);

String attributeValue = getAttributes(queryNode);

if(queryNode.getNodeName().equals("MODULE") && attributeValue.equals(moduleName)) {

NodeList childNodeList = queryNode.getChildNodes();

for(int i=0; i<childNodeList.getLength(); i++) {
String childAttributeValue = null;

Node childNode = childNodeList.item(i);

if(childNode.getNodeType() == Node.ELEMENT_NODE){
childAttributeValue = getAttributes(childNode);

if(childAttributeValue.trim().equals(queryName)){
System.out.println("Query: " + childNode.getTextContent().trim());
gtemQuery = childNode.getTextContent().trim();
break;
}
}
}
}
}
return gtemQuery;
}

public static String getAttributes(Node firstLevelNode) {

String attributeValue = null;

NamedNodeMap nodeMap = firstLevelNode.getAttributes();

for (int i=0; i<nodeMap.getLength(); i++) {
Node attributeNode = nodeMap.item(i);
// Get attribute value
attributeValue = attributeNode.getNodeValue();
System.out.println("Attribute Value: " + attributeValue );
}
return attributeValue;
}

}

Accessing an XML document using XPATH

Requirement:
We have a completely organized XML file with SQL Queries. We need to parse the XML file and retrieve only the SQL Queries based on module code and sql query id.


XML File (ABCSQLQueries):

<SQL_ROOT>
<MODULE CODE="REQUEST">
<SQL_SEQMENT ID="PAYMENTTERMS_QUERY">
SELECT A.PAYMENTTERMSKEY, A.DISPLAY FROM OWN_ABC.PAYMENTTERMS A, OWN_ABC.REQUESTDETAILS B WHERE
B.REQUESTDETAILSKEY = ? AND A.PAYMENTTERMSKEY = B.PAYMENTTERMSKEY
</SQL_SEQMENT>
<SQL_SEQMENT ID="REQUEST_UPDATE">
update request query
</SQL_SEQMENT>
</MODULE>
<MODULE CODE="BANK">
<SQL_SEQMENT ID="BANK_SELECT">
Select bank query
</SQL_SEQMENT>
<SQL_SEQMENT ID="BANK_UPDATE">
update bank query
</SQL_SEQMENT>
</MODULE>
<MODULE CODE="COUNTRY">
<SQL_SEQMENT ID="COUNTRY_SELECT">
Select country query
</SQL_SEQMENT>
<SQL_SEQMENT ID="COUNTRY_UPDATE">
update country query
</SQL_SEQMENT>
</MODULE>
</SQL_ROOT>

Code:

import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
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.NodeList;

import org.xml.sax.SAXException;

public class ABCSQLLoader {

static Document doc;
static Element element;
// Declare it in constants file and use it instead of hard-coding like this
private static String fileName = "ABCSQLQueries.xml";

Uncomment only for execution through console mode.
/*
public static void main(String[] args) {
XMLParser xr = new XMLParser();
xr.getXmlParser();
}
*/

public void getXmlParser() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

try {
DocumentBuilder builder = factory.newDocumentBuilder();
InputStream objInputStream = this.getClass().getResourceAsStream(fileName);
doc = builder.parse(objInputStream);
}catch(ParserConfigurationException parserException) {
}catch(SAXException saxException) {
}catch(IOException ioException) {
}catch(Exception exception){}

Uncomment only for execution through console mode.
//getSQLQuery("REQUEST", "PAYMENTTERMS_QUERY");
}

public static String getSQLQuery (String moduleName, String queryName) {
String sqlQuery = null;
try{
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
String expression ="SQL_ROOT/MODULE[@CODE='"+moduleName+"']/SQL_SEQMENT[@ID='"+queryName+"']/text()";
XPathExpression expr = xpath.compile(expression);
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
sqlQuery = nodes.item(0).getNodeValue();
System.out.println("Query: " + sqlQuery);
}
catch(Exception ex) {
System.out.println("......Error while parsing.....");
}
return sqlQuery;
}
}

How to apply this whole XML-SQL concept in a J2EE application?


Step-I: Load the XMLParser (ABCSQLLoader) while the J2EE web application starts in the server through a servlet’s init method.

public class PopulateApplicationDataServlet extends HttpServlet {

public void init(ServletConfig config) throws ServletException {
XMLParser parsing = new XMLParser();
parsing.getXmlParser();

}
}

Step-II:
Once the xml parser parse’s the XML file, give the module name and query name as parameters through normal java method call from the application DAO classes.

objResultSet = objStatement.executeQuery(ABCSQLLoader.getSQLQuery(
"REQUEST", " PAYMENTTERMS_QUERY ")
);