Parse XML files using Apache Commons Digester
Parse XML file using Apache Commons Digester Author: Anjana Date: Feb/17/2012
Introduction: The document demo’s the usage of Apache digester3.0 jar in parsing xml documents. The Digester is not an XML parser but just a high-level interface that uses SAX underneath to accomplish the actual XML parsing. So a requirement for Digester is the presence of an XML parser conforming to Java API for XML Processing (JAXP) version 1.1 or later. The java objects and xml are combined with set of rules to parse the XML document. The document gives various examples on apache-commons Digester. The document explores various options available with Commons-Digester3.0. Commons digester 3.0 jar has made parsing xml files easier compared to its previous versions.
1
Parse XML files using Apache Commons Digester
Key Points: 1. Digester uses a stack to store or retrieve objects as the XML file is being parsed. 2. Digester uses SAX to do the parsing, XML processing with Digester happens in an event-driven manner. An event-driven manner is when events are triggered while the document is being parsed; what you need to do is provide handlers for these events. 3. SAX events are fired on occurrences such as starting tags, ending tags, and so on
Pre-requisites: The below mentioned jar should be available in the class path of the application. • commons-digester3-3.2-with-deps
Parsing the XML file with repetitive elements: The below example is comprehensive and parses a complex xml file. We are considering 3 xml files: 1. test-service-config.xml 2. test-service-include.xml 3. test-service-include1.xml The test-service-config.xml file has
tag which contains test-serviceinclude.xml and test-service-include1.xml. Goal: Is to parse the included xml file and give list of service Objects.
2
Parse XML files using Apache Commons Digester
test-service-config.xml:
3
Parse XML files using Apache Commons Digester
test-service-include.xml
test-service-include1.xml 4
Parse XML files using Apache Commons Digester
Analyze the XML file: Tags
Pattern
Services Services/include Services/include/resource Services/service
Services/service/classname
Services/service/startup
Services/service/deployModel
Services/service/constructor
Services/service/constructor/param
Service/service/constructor/param/name
Service/service/constructor/param/value
Service/service/constructor/param/type
Service/service/init-method
Service/service/init-method/name
Service/service/init-method/ param
Service/service/init-method/param/name
Service/service/init-method/param/value
Service/service/init-method /param/type
5
Parse XML files using Apache Commons Digester
From the above table you can infer that is the root element of the document.
ServiceDigesterRulesModule.java that AbstractRuleModule use the above table for reference. Create
extends
the
package com.service.xmlparser; import org.apache.commons.digester3.binder.AbstractRulesModule; public class ServiceDigesterRulesModule extends AbstractRulesModule { @Override protected void configure() { forPattern("services").createObject().ofType("com.service.beans.ServicesRootN odeBean"). then().setProperties(); forPattern("services/include").createObject() .ofType("com.service.beans.IncludeBean") .then().setProperties() .then().setNext("addIncludeSet"); forPattern("services/include/resource").setBeanProperty(); forPattern("services/service").createObject() .ofType("com.service.beans.ServiceConfigBean") .then().setProperties() .then().setNext("addService"); forPattern("services/service/constructor").createObject() .ofType("com.service.beans.ConstructorNodeBean") .then().setProperties() .then().setNext("setCb"); forPattern("services/service/constructor/param").createObject() .ofType("com.service.beans.ParamNodeBean") .then().setProperties() .then().setNext("addpram");
forPattern("services/service/constructor/param/name").setBeanProperty(); forPattern("services/service/constructor/param/value").setBeanProperty(); forPattern("services/service/constructor/param/type").setBeanProperty();
forPattern("services/service/init-method").createObject() .ofType("com.service.beans.InitMethodNodeBean")
6
Parse XML files using Apache Commons Digester .then().setProperties() .then().setNext("setImb"); forPattern("services/service/init-method/param").createObject() .ofType("com.service.beans.ParamNodeBean") .then().setProperties() .then().setNext("addpram"); forPattern("services/service/initmethod/param/name").setBeanProperty(); forPattern("services/service/initmethod/param/value").setBeanProperty(); forPattern("services/service/initmethod/param/type").setBeanProperty(); } }
So we can have ServicesRootNodeBean.java class. This class is the root class that digester uses for parsing. The below class diagrams shows that ServicesBean Class with other Classes.
ServicesRootNodeBean private List serviceList; private Set includeSet;
addService(ServiceConfigBean) getServiceMap(List) getServiceList() setServiceList(List) addIncludeSet(IncludeBean) getIncludeSet() setIncludeSet(Set) 7
Parse XML files using Apache Commons Digester
ServiceConfigBean.java ServiceConfigBean private private private private private private private
String Id=null;; String classname=null;; String startup=null;; String deployModel=null;; Constructorbean cb; String type=null;; InitMethodbean imb;
getType() setType(String) getImb() setImb(InitMethodbean) getId() setId(String) getClassname() setClassname(String) getStartup() setStartup(String) getDeployModel() setDeployModel(String) getCb() setCb(Constructorbean) toString() ServiceBean()
8
Parse XML files using Apache Commons Digester
IncludeNodeBean.java IncludeNodeBean Private String resource=null; toString() Include() getResource() setResource(String)
ConstructorNodeBean.java ConstructorNodeBean.java
Private List paramList; getParamList() setParamList(List) Constructorbean() addpram(Param) toString()
9
Parse XML files using Apache Commons Digester
InitMethodNodeBean.java InitMethodNodeBean Private List paramList; Private String name; getParamList() setParamList(List) InitMethodbean() getName() setName(String) addpram(Param) toString()
ParamNodeBean.java ParamNodeBean.java String name; String value; String type; getParamList() setParamList(List) InitMethodbean() getName() setName(String) addpram(Param) toString() 10
Parse XML files using Apache Commons Digester
ServiceId.java ServiceId.java String
Id;
ServiceId() getId() setId(String) toString()
ServiceData.java ServiceData.java String name; String value; String type; ServiceData() ServiceData(ServiceConfigBean) getConfig() setConfig(ServiceConfigBean) toString()
11
Parse XML files using Apache Commons Digester
Binding the ServiceDigesterRulesModule with XMLServiceConfigHandler package com.service.xmlparser; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.commons.digester3.Digester; import org.apache.commons.digester3.binder.DigesterLoader; import org.xml.sax.SAXException; import com.service.beans.ServicesRootNodeBean; import com.service.xmlparser.ServiceContentHandlerDigester; public class XMLServiceConfigHandler { private Map servicesMap; private Set includeSet ; private DigesterLoader digesterLoader; private ServicesRootNodeBean result = null; private Digester digester; public XMLServiceConfigHandler() { servicesMap = new HashMap(); includeSet = new HashSet(); digester=new ServiceContentHandlerDigester(); } private void initDigester(){ digesterLoader= DigesterLoader.newLoader(new ServiceDigesterRulesModule()); digester= digesterLoader.newDigester(); } /*Make this as an input stream*********************/ public void Load(InputStream inputStream){ try { initDigester(); result = digester.parse(inputStream); setValues(result); } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { 12
Parse XML files using Apache Commons Digester
e.printStackTrace(); } } private void setValues(ServicesRootNodeBean result) { if(result!=null){ setIncludeSet(result.getIncludeSet()); setServicesMap(result.getServiceMap(result.getServiceList() )); } } public Set getIncludeSet() { return includeSet; } public void setIncludeSet(Set includeSet) { this.includeSet = includeSet; } public Map getServicesMap() { return servicesMap; } public void setServicesMap(Map servicesMap) { this.servicesMap = servicesMap; } @Override public String toString() { return "XMLServiceConfigHandler [servicesMap=" + servicesMap + ", includeSet=" + includeSet + "]"; } }
The Object of the above file can be created in a main program and pass the .xml file as an input stream.
13
Parse XML files using Apache Commons Digester
Main.java package com.service.test; import java.io.InputStream; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import com.service.beans.IncludeBean; import com.service.xmlparser.XMLServiceConfigHandler; public class Main { public static void main(String args[]) { Map servicesMap=new HashMap(); Set includeSet= new HashSet(); XMLServiceConfigHandler xsch = new XMLServiceConfigHandler(); InputStream inputStream Main.class.getClassLoader().getResourceAsStream("test-services-config.xml"); xsch.Load(inputStream); includeSet=xsch.getIncludeSet(); servicesMap=xsch.getServicesMap(); System.out.println("includeSet"+includeSet); 14
=
Parse XML files using Apache Commons Digester
System.out.println("servicesMap"+servicesMap); if(includeSet!=null && includeSet.size()!=0){ Iterator it = includeSet.iterator(); while (it.hasNext()) { IncludeBean include = (IncludeBean) it.next(); System.out.println("\n >"+include.getResource()); XMLServiceConfigHandler XMLServiceConfigHandler();
Parsing-xsch1
=
InputStream inputStream1 Main.class.getClassLoader().getResourceAsStream(include.getResource()); xsch1.Load(inputStream1); includeSet=xsch1.getIncludeSet(); servicesMap=xsch1.getServicesMap(); System.out.println("includeSet"+includeSet); System.out.println(" servicesMap"+servicesMap); } } } }
15
new =
Parse XML files using Apache Commons Digester
Class Diagrams Bean Package-
16
Parse XML files using Apache Commons Digester
Xmlparser package
17