I have an xml having same tags (<value> tag) as given below:

<number>
<type>decimal</type>
<value>12</value>
<value>14</value>
</number>

I am trying to parse using either Digester or JAXB (without Schema). What I have done is I have created a java class that will map with the given xml. For this I have getter and setter methods for the <type> tag as:

String type;
public String getType() {
		return type;
}

public void setType(String type) {
		this.type = type;
}

In Digester Rule xml file I have added the binding rule for the <type> tag as:

<bean-property-setter-rule pattern="type"/>
This will map the <type> tag in the xml with the 'type' property in the java class.

My problem is how to map <value> tag with the java class ?
How will I create the getter and setter methods for the <value> tag and also how will I set its digester rule in the Digester Rule xml file.
I need to store the values to either ArrrayList or Vector.

Thanks in advance.

Member Avatar for ztini

JAXB actually makes this extremely easy to do through annotations:

Consider a number class like this:

import java.util.ArrayList;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "number")
public class Number {
	
	private String type;
	private ArrayList<Integer> values = new ArrayList<Integer>();

	@XmlElement
	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	@XmlElements(value = { @XmlElement(name = "value") })
	public ArrayList<Integer> getValues() {
		return values;
	}

	public void setValues(ArrayList<Integer> values) {
		this.values = values;
	}

}

And an unmarshaller class:

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

public class XML {
	
	public static Number parseNumber(File xml) throws JAXBException { 
		JAXBContext jaxbContext = JAXBContext.newInstance(Number.class);
		Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
		return (Number) unmarshaller.unmarshal(xml);
	}

}

There is an assortment of ways you can map the xml to POJO's using these annotations. The full documentation is found here: http://docs.oracle.com/javaee/5/api/javax/xml/bind/annotation/package-summary.html

commented: Thanks for elaborating with full code +1

Try wrapping the `value` elements in a parent element called `values` and have a look at this thread.

Thanks to all who replied..

I have found a solution for this post using Digester.
I don't know whether this is a corect way or not, but i am able to get the result.

Here i am pasting the codes:

1) Input xml- MyTestXML.xml

<?xml version="1.0" encoding="UTF-8"?>
<number>
	<type>Decimal</type>
	<value>14</value>
	<value>16</value>
</number>

2) Java class that maps to the input xml - MyTestXML.java

import java.util.Vector;
public class MyTestXML {

	//String value; //Removed
	String type;
	Vector valueVec = new Vector();
	
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	
	/* I've removed this getter method as it is of no use.
	 public String getValue() {
		return value;
	}
	
	*/
	
	//I made some modification in this setter method for value 
	public void setValue(String val) {
		valueVec.addElement(val);
		//this.value = value;   //Removed

	}

	//I have manually added this getter method to get the vector object.
	public Vector getValueVec(){
		return valueVec;

		}
}

3) Digester rules XML file - MyTestXMLDigesterRules

<?xml version="1.0" encoding="UTF-8"?>
<digester-rules>
	<pattern value = "number">
		<object-create-rule classname= "com.spring.myDigester.MyTextXML"/>
		<bean-property-setter-rule pattern="type"/>
        <bean-property-setter-rule pattern="value"/>
	</pattern>
</digester-rules>

4) Main Class - MyTestXMLmain.java

import java.io.IOException;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.xmlrules.DigesterLoader;
import org.xml.sax.SAXException;

public class MyTestXMLmain {

	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyTestXMLmain  objMain = new MyTestXMLmain();
			objMain.digest();
	}

	private void digest() {
		// TODO Auto-generated method stub
		Digester digester = DigesterLoader.createDigester(
	               this.getClass().getClassLoader().getResource("MyTestXMLDigesterRules.xml"));	
		
		try {
			
			MyTestXML ee = (MyTestXML) digester.parse(this.getClass().getClassLoader().getResourceAsStream("MyTestXML.xml"));
				
			System.out.println("Type In Main: "+ee.getType());
			System.out.println("Value In Main: "+ee.getValueVec());
			
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}

Result:

Type In Main: Decimal
Value In Main: [14, 16]

If there is any other way using digester, please reply to this post.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.