Many To Many Hibernate Mapping using mapping table

We consider the scenario where one author can write many books and one book can have many authors. This is a many to many relationship that uses a mapping table to manage the many to many associations between authors and books.
The following queries can setup such a database for you.

drop database pubs;
create database pubs;
use pubs;
drop table TB_AUTHORS;
CREATE TABLE TB_AUTHORS (AUTHOR_ID int(11) NOT NULL default '0',AUTHOR_NAME varchar(30) default NULL,PRIMARY KEY (AUTHOR_ID)) ;
drop table TB_BOOKS;
CREATE TABLE TB_BOOKS (ISBN_CODE varchar(10) NOT NULL, BOOK_TITLE varchar(30) default NULL,PRIMARY KEY (ISBN_CODE)) ;
drop table TB_AUTHORS_BOOKS;
CREATE TABLE TB_AUTHORS_BOOKS (AUTHOR_ID_IN_MAP int(11) NOT NULL, ISBN_CODE varchar(10) not NULL);

The domain classes look like this

package com.mattiz.persistence.beans;
// Generated 18 Jan, 2014 6:01:04 AM by Hibernate Tools 3.2.2.GA


import java.util.HashSet;
import java.util.Set;

/**
 * Author generated by hbm2java
 */
public class Author  implements java.io.Serializable {
     private int authorId;
     private Set books = new HashSet(0);
     private String name;

    public Author() {
    }

    public Author(Set books, String name) {
       this.books = books;
       this.name = name;
    }
   
    public int getAuthorId() {
        return this.authorId;
    }
    
    public void setAuthorId(int authorId) {
        this.authorId = authorId;
    }
    public Set getBooks() {
        return this.books;
    }
    
    public void setBooks(Set books) {
        this.books = books;
    }
    public String getName() {
        return this.name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
}
package com.mattiz.persistence.beans;
// Generated 18 Jan, 2014 6:01:04 AM by Hibernate Tools 3.2.2.GA



/**
 * Book generated by hbm2java
 */
public class Book  implements java.io.Serializable {
     private String isbn;
     private String title;

    public Book() {
    }
	
    public Book(String isbn) {
        this.isbn = isbn;
    }
    public Book(String isbn, String title) {
       this.isbn = isbn;
       this.title = title;
    }
   
    public String getIsbn() {
        return this.isbn;
    }
    
    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }
    public String getTitle() {
        return this.title;
    }
    
    public void setTitle(String title) {
        this.title = title;
    }
}

The above class files are generated from the hbm2java tool(See details at bottom)
The corresponding hbm files look like this
Author.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <class name="com.mattiz.persistence.beans.Author" lazy="false" table="TB_AUTHORS" >
        <id name="authorId" column="AUTHOR_ID" length="11" type="int" >
        	<generator class="increment"></generator>
        </id>
        <set name="books" table="TB_AUTHORS_BOOKS" cascade="save-update" lazy="false">
            <key column="AUTHOR_ID_IN_MAP" />
            <many-to-many column="ISBN_CODE"  class="com.mattiz.persistence.beans.Book" />
        </set>
        <property name="name" type="java.lang.String" column="AUTHOR_NAME" length="30" />
    </class>
</hibernate-mapping>

Book.hbml.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping>
	<class name="com.mattiz.persistence.beans.Book" table="TB_BOOKS" lazy="false">
		<id name="isbn" column="ISBN_CODE" length="10" type="java.lang.String" >
			<generator class="assigned"></generator>
		</id>
		<property name="title" type="java.lang.String" column="BOOK_TITLE" length="30" />
	</class>
</hibernate-mapping>

The Dao class and interface:
IMattizDao.java

package com.mattiz.persistence.data;

import java.util.Set;

import org.springframework.dao.DataAccessException;

import com.mattiz.persistence.beans.Author;
import com.mattiz.persistence.beans.Book;

public interface IMattizDao {

	public Set<Book> getBooksForAuthor(int authorId) throws DataAccessException;

	public void insertAuthor(String authorName, Set<Book> books)
			throws DataAccessException;

}

MattizDao.java

package com.mattiz.persistence.data;

import java.util.Set;

import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.mattiz.persistence.beans.Author;
import com.mattiz.persistence.beans.Book;

public class MattizDao implements IMattizDao {

	private HibernateTemplate hibernateTemplate;

	public Set<Book> getBooksForAuthor(int authorId) throws DataAccessException {
		Author authorBean = null;
		authorBean = (Author) getHibernateTemplate().load(Author.class,
				authorId);
		System.out.println(authorBean.getName()+"n");
		Set<Book> books = authorBean.getBooks();
		for(Book b: books){
			System.out.println(b.getTitle());
		}	
		return books;
	}

	public void insertAuthor(String authorName, Set<Book> books)
			throws DataAccessException {
		Author authorBean = new Author();
		authorBean.setBooks(books);
		authorBean.setName(authorName);
		HibernateTemplate template = getHibernateTemplate();
		template.saveOrUpdate(authorBean);
		System.out.println("Inserted/Updated AuthorBean "
				+ authorBean.getName());
	}

	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}
}

The service class and interface
IMattizDelegate.java

package com.mattiz.service.spring;

import java.util.Set;

import com.mattiz.persistence.beans.Book;
import com.mattiz.persistence.data.IMattizDao;

public interface IMattizDelegate {

	public void insertAuthor(String authorName, Set<Book> books);

	public Set<Book> getBooksForAuthor(int authorId);

	public IMattizDao getMattizDao();

	public void setMattizDao(IMattizDao mattizDao);

}

MattizDelegate.java

package com.mattiz.service.spring;

import java.util.Set;

import com.mattiz.persistence.beans.Book;
import com.mattiz.persistence.data.IMattizDao;

public class MattizDelegate implements IMattizDelegate {

	private IMattizDao mattizDao;

	public void insertAuthor(String authorName, Set<Book> books) {
		getMattizDao().insertAuthor(authorName, books);
	}

	public Set<Book> getBooksForAuthor(int authorId) {
		Set<Book> books = getMattizDao().getBooksForAuthor(authorId);
		return books;
	}

	public IMattizDao getMattizDao() {
		return mattizDao;
	}

	public void setMattizDao(IMattizDao mattizDao) {
		this.mattizDao = mattizDao;
	}

}

The Main class that is a replacement for a front end UI
MattizMain.java

package com.mattiz.web.managedbeans;

import java.util.HashSet;
import java.util.Set;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.mattiz.persistence.beans.Book;
import com.mattiz.service.spring.IMattizDelegate;

public class MattizMain {

	private ApplicationContext applicationContext;

	private IMattizDelegate mattizDelegate;

	public IMattizDelegate getMattizDelegate() {
		mattizDelegate = (IMattizDelegate) applicationContext
				.getBean("mattiz.service.delegate");
		return mattizDelegate;
	}

	public void setMattizDelegate(IMattizDelegate mattizDelegate) {
		this.mattizDelegate = mattizDelegate;
	}

	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	public void setApplicationContext(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}

	public static void main(String[] args) {
		MattizMain mattizMain = new MattizMain();
		mattizMain.applicationContext = new ClassPathXmlApplicationContext(
				"resources/mattiz.xml");
		Book a = new Book("1e","The Cool Drink");
		Book b = new Book("1a","Lost Island");
		Book c = new Book("1b","Treasure Hunt");
		Book d = new Book("1c","Down With Fever");
		Book e = new Book("1d","Imagination runs Wild");
		Book f = new Book("1r","The Wild West");
		Book g = new Book("1h","Gregorios");
		Book h = new Book("14","Mar Thoma");
		Book i = new Book("15","Christ and the Disciples");
		Book j = new Book("1t","Long live His Cotton Socks");
		Book k = new Book("19","Praise Be to Harman!");
		Set<Book> aa = new HashSet<Book>();
		aa.add(a);
		aa.add(b);
		aa.add(c);		
		aa.add(d);
		aa.add(e);
		aa.add(f);
		aa.add(g);
		Set<Book> ab = new HashSet<Book>();
		ab.add(a);		
		ab.add(b);
		ab.add(h);
		Set<Book> ac = new HashSet<Book>();
		ac.add(i);
		ac.add(j);		
		ac.add(k);
		Set<Book> ad = new HashSet<Book>();
		ad.add(a);		
		ad.add(k);	
		Set<Book> af = new HashSet<Book>();
		af.add(a);
		Set<Book> ag = new HashSet<Book>();
		ag.add(a);	
		Set<Book> ah = new HashSet<Book>();
		ah.add(e);	
		Set<Book> aj = new HashSet<Book>();
		aj.add(f);	
		mattizMain.getMattizDelegate().insertAuthor("Mac",aa);
		mattizMain.getMattizDelegate().insertAuthor("Kenzie", ab);
		mattizMain.getMattizDelegate().insertAuthor("John",ac);		
		mattizMain.getMattizDelegate().insertAuthor("Warbler",ad);
		mattizMain.getMattizDelegate().insertAuthor("Huan",af);
		mattizMain.getMattizDelegate().insertAuthor("Mike",ag);
		mattizMain.getMattizDelegate().insertAuthor("Don",ag);		
		mattizMain.getMattizDelegate().insertAuthor("John",ah);
		mattizMain.getMattizDelegate().insertAuthor("Mark",aj);
		mattizMain.getMattizDelegate().insertAuthor("Jim",ah);
		mattizMain.getMattizDelegate().insertAuthor("Joe",ah);
		mattizMain.getMattizDelegate().insertAuthor("Harry",ad);		
		mattizMain.getMattizDelegate().insertAuthor("Noman",ag);
		mattizMain.getMattizDelegate().insertAuthor("Julian",aj);
		mattizMain.getMattizDelegate().insertAuthor("Tick",af);
		mattizMain.getMattizDelegate().insertAuthor("Toe",ac);
		mattizMain.getMattizDelegate().getBooksForAuthor(1);
		System.out.println("----------------------");
		mattizMain.getMattizDelegate().getBooksForAuthor(5);
	}

}

Spring configuration file:
mattiz.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean
        id="mattiz.hibernate.dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" >
        <property name="driverClass" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/pubs" />
        <property name="user" value="root" />
        <property name="password" value="admin" />
    </bean>
    <bean id="mattiz.abstract.hibernate.sessionfactory" abstract="true" 
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" lazy-init="true" >
        <property name="dataSource" >
            <ref local="mattiz.hibernate.dataSource" />
        </property>
        <property name="hibernateProperties" >
            <props>
                <prop key="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql" >false</prop>
            </props>
        </property>
    </bean>
    <bean id="mattiz.pageSize" class="java.lang.Integer" >
        <constructor-arg value="5000" >
        </constructor-arg>
    </bean>
    <bean id="mattiz.hibernate.sessionfactory" parent="mattiz.abstract.hibernate.sessionfactory" >
        <property name="mappingResources" >
            <list>
                <value>resources/Author.hbm.xml</value>
                <value>resources/Book.hbm.xml</value>
            </list>
        </property>
    </bean>
    <bean id="mattiz.transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" >
        <property name="sessionFactory" >
            <ref bean="mattiz.hibernate.sessionfactory" />
        </property>
    </bean>
    <bean id="mattiz.hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate" >
        <property name="sessionFactory" >
            <ref bean="mattiz.hibernate.sessionfactory" />
        </property>
    </bean>
    <bean id="mattiz.dao.mattizDAO" class="com.mattiz.persistence.data.MattizDao" singleton="true" >
        <property name="hibernateTemplate" >
            <ref bean="mattiz.hibernateTemplate" />
        </property>
    </bean>
    <bean id="mattiz.client" class="com.mattiz.web.managedbeans.MattizMain" singleton="true" >
        <property name="mattizDelegate" ref="mattiz.service.delegate" />
    </bean>
    <bean id="mattiz.service.delegate" class="com.mattiz.service.spring.MattizDelegate" singleton="true" >
        <property name="mattizDao" ref="mattiz.dao.mattizDAO" />
    </bean>
</beans>

Screenshots show structure of file heirarchy, jars and APIs used and SQL output
many_many
library_ref
mapping_table_insertions

The domain files are generated from the hbml.xml hibernate files. For easy reference the code is given below:
The Author.hbm.xml and Book.hbm.xml described above are placed in the “src” folder. The generated java domain classes are created under “generated/src/com/mattiz/persistence/beans” folder.
The jars used for this purpose can be seen in the screenshot.
The only additional piece of code is the build file described below:

build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project default="codegen">
	<target name="codegen">
		<path id="classpath_id">
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.apache.commonscom.springsource.org.apache.commons.beanutils1.8.0com.springsource.org.apache.commons.beanutils-1.8.0.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.apache.commonscom.springsource.org.apache.commons.logging1.1.1com.springsource.org.apache.commons.logging-1.1.1.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.dom4jcom.springsource.org.dom4j1.6.1com.springsource.org.dom4j-1.6.1.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.hibernatecom.springsource.org.hibernate3.3.1.GAcom.springsource.org.hibernate-3.3.1.GA.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.hibernatecom.springsource.org.hibernate.annotations3.4.0.GAcom.springsource.org.hibernate.annotations-3.4.0.GA.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.apache.log4jcom.springsource.org.apache.log4j1.2.15com.springsource.org.apache.log4j-1.2.15.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.apache.commonscom.springsource.org.apache.commons.collections3.2.1com.springsource.org.apache.commons.collections-3.2.1.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.slf4jcom.springsource.slf4j.api1.5.3com.springsource.slf4j.api-1.5.3.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.slf4jcom.springsource.slf4j.jcl1.5.3com.springsource.slf4j.jcl-1.5.3.jar" />
<pathelement location="I:packageshibernate-tools.jarhibernate-tools.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.freemarkercom.springsource.freemarker2.3.15com.springsource.freemarker-2.3.15.jar" />
		</path>
		<echo>Zippzip</echo>
		<taskdef name="hibernatetool" classname="org.hibernate.tool.ant.HibernateToolTask">
			<classpath refid="classpath_id" />
		</taskdef>
		<hibernatetool destdir="generated/src">
			<configuration>
				<fileset dir=".">
					<include name="src/*.hbm.xml" />
				</fileset>
			</configuration>
			<hbm2java />
		</hibernatetool>
	</target>
</project>

DomainGenerator

The hibernate domain generator can be downloaded here

The many to many hibernate mapping source code can be downloaded here

Merging XML files using XPath

This example is a solution to a commonplace XML problem – merging two XML files into one. Our two input XMLs will not have any indexes mapping one node to another but it is under the assumption that there is a one to one correspondence between the nodes of each XML based on their location in the XML file.
Instead of using user friendly XML parsers such as JDOM and XercesJ we use a less resource intensive light weight technology – XPath that comes bundled with the Java SDK.

Here is the first input XML:

XmlOne.xml

<?xml version="1.0" encoding="UTF-8"?>
<Mattiz>
    <Content>
        <Name>Jo</Name>
        <RollNumber>3</RollNumber>
    </Content>
    <Content>
        <Name>Jack</Name>
        <RollNumber>7</RollNumber>
    </Content>
    <Content>
        <Name>Harrison</Name>
        <RollNumber>14</RollNumber>
    </Content>
    <Content>
        <Name>Mike</Name>
        <RollNumber>26</RollNumber>
    </Content>
    <Content>
        <Name>Mick</Name>
        <RollNumber>98</RollNumber>
    </Content>
    <Content>
        <Name>Jake</Name>
        <RollNumber>101</RollNumber>
    </Content>
    <Content>
        <Name>Tintin</Name>
        <RollNumber>238</RollNumber>
    </Content>
    <Content>
        <Name>Goldie</Name>
        <RollNumber>500</RollNumber>
    </Content>
    <Content>
        <Name>Sommer</Name>
        <RollNumber>501</RollNumber>
    </Content>
    <Content>
        <Name>Hayley</Name>
        <RollNumber>567</RollNumber>
    </Content>
</Mattiz>

The second input XML – XmlTwo.xml

<?xml version="1.0" encoding="UTF-8"?>
<Mattiz>
    <Content>
        <Name>Jo</Name>
        <Age>7</Age>
    </Content>
    <Content>
        <Name>Jack</Name>
        <Age>10</Age>
    </Content>
    <Content>
        <Name>Harrison</Name>
        <Age>11</Age>
    </Content>
    <Content>
        <Name>Mike</Name>
        <Age>15</Age>
    </Content>
    <Content>
        <Name>Mick</Name>
        <Age>16</Age>
    </Content>
    <Content>
        <Name>Jake</Name>
        <Age>16</Age>
    </Content>
    <Content>
        <Name>Tintin</Name>
        <Age>18</Age>
    </Content>
    <Content>
        <Name>Goldie</Name>
        <Age>21</Age>
    </Content>
    <Content>
        <Name>Sommer</Name>
        <Age>71</Age>
    </Content>
    <Content>
        <Name>Hayley</Name>
        <Age>100</Age>
    </Content>
</Mattiz>

And here is the Main class that does the merging:
MergeXml.java

package com.mattiz.merge.xml;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
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.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class MergeXml {

	public static void main(String args[]) throws ParserConfigurationException,
			SAXException, IOException, XPathExpressionException,
			TransformerException {
		XPathFactory xPathFactory = XPathFactory.newInstance();
		XPath xpath = xPathFactory.newXPath();
		DocumentBuilderFactory domFactory = DocumentBuilderFactory
				.newInstance();
		domFactory.setNamespaceAware(true);
		DocumentBuilder builder = domFactory.newDocumentBuilder();
		Document doc1 = builder.parse("./resources/XmlOne.xml");
		Document doc2 = builder.parse("./resources/XmlTwo.xml");
		String xPathString = "/Mattiz/Content";
		Document mergedDoc = passThroughXML(xpath, xPathString, doc1, doc2);
		System.out.println(getDocumentAsStringAfterTransformation(mergedDoc));
	}

	private static Document passThroughXML(XPath xpath, String xPathString,
			Document doc1, Document doc2) throws XPathExpressionException,
			TransformerException, IOException {
		Document document = null;
		XPathExpression xPathExpression = xpath.compile(xPathString);
		NodeList nodeList = (NodeList) xPathExpression.evaluate(doc2,
				XPathConstants.NODESET);
		for (int i = 0; i < nodeList.getLength(); i++) {
			XPathExpression innerXpathExpression = xpath.compile(xPathString
					.concat("[position()=" + (i + 1) + "]"));
			document = mergeXml(innerXpathExpression, doc1, doc2);
		}
		document = removeDuplicates(xPathString, xpath, document);
		return document;
	}

	private static Document mergeXml(XPathExpression innerXpathExpression,
			Document doc1, Document doc2) throws XPathExpressionException,
			IOException {
		Node doc1Node = (Node) innerXpathExpression.evaluate(doc1,
				XPathConstants.NODE);
		if (doc1Node == null) {
			throw new RuntimeException(doc1Node
					+ " - expression does not evaluate to a node");
		}
		Node doc2Node = (Node) innerXpathExpression.evaluate(doc2,
				XPathConstants.NODE);
		while (doc2Node.hasChildNodes()) {
			Node childNode = doc2Node.getFirstChild();
			doc2Node.removeChild(childNode);
			childNode = doc1.importNode(childNode, true);
			doc1Node.appendChild(childNode);
		}
		return doc1;
	}

	private static Document removeDuplicates(String xPathString, XPath xpath,
			Document document) throws XPathExpressionException,
			TransformerException {
		XPathExpression xPathExpression = xpath.compile(xPathString
				.concat("/Name[position()=2]"));
		NodeList nodeList = (NodeList) xPathExpression.evaluate(document,
				XPathConstants.NODESET);
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node nodeToRemove = nodeList.item(i);
			nodeToRemove.getParentNode().removeChild(nodeToRemove);
		}
		return document;
	}

	private static String getDocumentAsStringAfterTransformation(Document document)
			throws TransformerConfigurationException, TransformerException {
		TransformerFactory transformerFactory = TransformerFactory
				.newInstance();
		Transformer transformer = transformerFactory.newTransformer();
		DOMSource source = new DOMSource(document);
		Writer outWriter = new StringWriter();
		Result result = new StreamResult(outWriter);
		transformer.transform(source, result);
		String stringDoc = outWriter.toString();
		return stringDoc;
	}
}

The output XML that is generated looks something like this on the console:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  <Mattiz>
    <Content>
        <Name>Jo</Name>
        <RollNumber>3</RollNumber>        
        <Age>7</Age>
    </Content>
    <Content>
        <Name>Jack</Name>
        <RollNumber>7</RollNumber>        
        <Age>10</Age>
    </Content>
    <Content>
        <Name>Harrison</Name>
        <RollNumber>14</RollNumber>        
        <Age>11</Age>
    </Content>
    <Content>
        <Name>Mike</Name>
        <RollNumber>26</RollNumber>        
        <Age>15</Age>
    </Content>
    <Content>
        <Name>Mick</Name>
        <RollNumber>98</RollNumber>        
        <Age>16</Age>
    </Content>
    <Content>
        <Name>Jake</Name>
        <RollNumber>101</RollNumber>        
        <Age>16</Age>
    </Content>
    <Content>
        <Name>Tintin</Name>
        <RollNumber>238</RollNumber>        
        <Age>18</Age>
    </Content>
    <Content>
        <Name>Goldie</Name>
        <RollNumber>500</RollNumber>        
        <Age>21</Age>
    </Content>
    <Content>
        <Name>Sommer</Name>
        <RollNumber>501</RollNumber>
        <Age>71</Age>
    </Content>
    <Content>
        <Name>Hayley</Name>
        <RollNumber>567</RollNumber>       
        <Age>100</Age>
    </Content>
</Mattiz>

[purchase_link id=”0″ style=”” color=”” text=”Purchase”]file_struct

The source code can be downloaded here