There a lot of ways to read data from XML. The most common ones are: XPath, XSLT and XQuery.
- XPath consists of path expressions, conditions and some XPath functions
- XSLT(Extensible Stylesheet Language (with) Transformation) consists of XPath and some transformations
- XQuery consists of XPath and a Query Language. This query language is pretty powerful but it does not have strong underlying mathematics like SQL.
In this tutorial we will develop a simple XPath XML file parser. But as you probably know, there are different kind of parsers:
- DOM(Document Object Model) parsers. DOM API creates a DOM tree in memory for a XML document
- SAX(Simple API For XML) parsers. They are event driven(as they parse documents they invoke the callback methods)
As an example XML file we will use JBoss 5.1 datasource file. Here it is:
<?xml version="1.0" encoding="UTF-8"?> <datasources> <xa-datasource> <jndi-name>DevDbDS</jndi-name> <!-- <use-java-context>false</use-java-context> --> <xa-datasource-class> com.mysql.jdbc.jdbc2.optional.MysqlXADataSource </xa-datasource-class> <xa-datasource-property name="URL"> URL:jdbc:mysql://localhost:3306/dev_db </xa-datasource-property> <user-name>root</user-name> <password>root</password> <!-- <security-domain>VocdmsDSEncryptedLogon</security-domain> --> <xa-datasource-property name="characterEncoding">UTF-8</xa-datasource-property> <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name> <min-pool-size>5</min-pool-size> <max-pool-size>20</max-pool-size> <blocking-timeout-millis>30000</blocking-timeout-millis> <idle-timeout-minutes>15</idle-timeout-minutes> <prefill>true</prefill> <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation> <connection-property name="characterEncoding">UTF-8</connection-property> <connection-property name="autoReconnect">true</connection-property> <connection-property name="maxReconnects">4</connection-property> <connection-property name="initialTimeout">3</connection-property> <metadata> <type-mapping>mySQL</type-mapping> </metadata> </xa-datasource> </datasources>
Next we need to remind ourselves how to write XPath expressions. You can do it here
Now finally we are ready to write the code to get some information from the datasource. In this example let's assume we need user name, password and URL(you may need this data to establish java.sql.Connection). So here is our code:
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import java.io.*; public class XmlParser { //Immutable object for data storage private static class ConnectionInfo { private final String url; private final String userName; private final String password; public ConnectionInfo(String url, String userName, String password) { this.url = url; this.userName = userName; this.password = password; } public String getUrl() { return url; } public String getUserName() { return userName; } public String getPassword() { return password; } @Override public String toString() { return "URL: " + url + "\nuserName: " + userName + "\npassword: " + password; } } public static void main(String[] args) { System.out.println(parseDataSource("mysql-ds.xml")); } public static ConnectionInfo parseDataSource(String fileName) { try { DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(true); // never forget this! DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse(new FileInputStream(fileName)); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); String url = xpath.evaluate("//datasources/xa-datasource/xa-datasource-property[@name='URL']/text()", doc).trim(); String userName = xpath.evaluate("//datasources/xa-datasource/user-name/text()", doc).trim(); String password = xpath.evaluate("//datasources/xa-datasource/password/text()", doc).trim(); return new ConnectionInfo(url, userName, password); } catch (Exception ex) { ex.printStackTrace(); return null; } } }