JAXB ile Java-XML Mapping

JAXB (Java Xml Binding – https://jaxb.dev.java.net/) frameworkü kullanılarak Xml–>Java, Java–>Xml mapping işlemlerini gerçekleştirmek mümkündür. Bu yazılımcıya, Xml dosyalarının ihtiva ettiği verileri Java sınıflarıyla modelleme imkanı sunmakta ve verilerın işlenmesini kolaylaştırmaktadır. JAXB’nın nasıl kullanılabileceğini bir örnek üzerinde sizlere aktarmak istiyorum.

Aşağıda bir arabayı modelleyen bir DTD dosyası yer almaktadır.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!ELEMENT Tasit (araba*)>
<!ELEMENT araba (model, motor)>
<!ELEMENT model (#PCDATA)>
<!ELEMENT motor (beygirgucu, tipi)>
<!ELEMENT beygirgucu (#PCDATA)>
<!ELEMENT tipi (#PCDATA)>

Bu DTD dosyasını kullanarak JAXB yardımı ile Java mapping sınıfları oluşturabiliriz. Bu işlemi Ant ile yapmak mümkündür.


<property name="jaxb.home" value="${basedir}/lib/jaxb" />

<path id="classpath">
<pathelement path="src" />
<pathelement path="classes" />
<pathelement path="schemas" />

<fileset dir="${jaxb.home}" includes="*.jar" />

</path>

<taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask">
<classpath refid="classpath" />
</taskdef>

<target name="tasit" description="">

<mkdir dir="gen-src" />
<xjc schema="${basedir}/etc/jaxb/test/Tasit.dtd" binding="${basedir}/etc/jaxb/test/Tasit.jaxb" destdir="${basedir}/gen-src">
<arg value="-dtd" />
<produces dir="gen-src" includes="**/*.java" />
</xjc>
</target>

jaxb.home isminde bir değişken ile JAXB paketinin ihtiva ettiği Jar dosyalarının yerini tanımlıyoruz. Xml den türetilen Java sınıflarını oluşturabilmek için com.sun.tools.xjc.XJCTask sınıfını kullanıyoruz.

DTD dosyasından Java sınıflarını oluşturabilmemiz için tasit.jaxb isminde bir konfigürasyon dosyası oluşturmamız gerekmektedir. Bu dosyanın içeriği aşağıdaki şekildedir:

<?xml version="1.0" ?>
<!--
The syntax of the binding file for DTD is defined in the JAXB EA.
See vendorSchemaLangs.html for details.
-->
<xml-java-binding-schema xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc">

<!-- specify the package name for the generated code -->
<options package="com.tasit.mapping" />

<!--
additional optional XJC specific extensions
are available as follows
-->
<xjc:serializable uid="5" />

</xml-java-binding-schema>

Java sınıflarını oluşturmak için Ant dosyasında tanımladığımız tasit isimli hedefi (target) koşturuyoruz. tasit hedefinde belirttiğimiz gibi Java sınıfları xjc tarafından oluşturulduktan sonra gen-src dizine yerleştirileceklerdir.

JAXB tarafından oluşturulan sınıflar aşağıda yer almaktadır.

package com.tasit.mapping;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

/**
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"model",
"motor"
})
@XmlRootElement(name = "araba")
public class Araba {

@XmlElement(required = true)
protected String model;
@XmlElement(required = true)
protected Motor motor;

/**
* Gets the value of the model property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getModel() {
return model;
}

/**
* Sets the value of the model property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setModel(String value) {
this.model = value;
}

/**
* Gets the value of the motor property.
*
* @return
* possible object is
* {@link Motor }
*
*/
public Motor getMotor() {
return motor;
}

/**
* Sets the value of the motor property.
*
* @param value
* allowed object is
* {@link Motor }
*
*/
public void setMotor(Motor value) {
this.motor = value;
}

}

package com.tasit.mapping;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

/**
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"beygirgucu",
"tipi"
})
@XmlRootElement(name = "motor")
public class Motor {

@XmlElement(required = true)
protected String beygirgucu;
@XmlElement(required = true)
protected String tipi;

/**
* Gets the value of the beygirgucu property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getBeygirgucu() {
return beygirgucu;
}

/**
* Sets the value of the beygirgucu property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setBeygirgucu(String value) {
this.beygirgucu = value;
}

/**
* Gets the value of the tipi property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getTipi() {
return tipi;
}

/**
* Sets the value of the tipi property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setTipi(String value) {
this.tipi = value;
}

}
package com.tasit.mapping;

import javax.xml.bind.annotation.XmlRegistry;

/**
* This object contains factory methods for each
* Java content interface and Java element interface
* generated in the com.tasit.mapping package.
* <p>An ObjectFactory allows you to programatically
* construct new instances of the Java representation
* for XML content. The Java representation of XML
* content can consist of schema derived interfaces
* and classes representing the binding of schema
* type definitions, element declarations and model
* groups. Factory methods for each of these are
* provided in this class.
*
*/
@XmlRegistry
public class ObjectFactory {


public ObjectFactory() {
}

/**
* Create an instance of {@link Motor }
*
*/
public Motor createMotor() {
return new Motor();
}

/**
* Create an instance of {@link Araba }
*
*/
public Araba createAraba() {
return new Araba();
}

/**
* Create an instance of {@link Tasit }
*
*/
public Tasit createTasit() {
return new Tasit();
}

}

package com.tasit.mapping;

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

/**
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"araba"
})
@XmlRootElement(name = "Tasit")
public class Tasit {

protected List<Araba> araba;

/**
* Gets the value of the araba property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the araba property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getAraba().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link Araba }
*
*
*/
public List<Araba> getAraba() {
if (araba == null) {
araba = new ArrayList<Araba>();
}
return this.araba;
}

}

Şimdi Tasit.dtd den türetilmiş bir Xml dosyasında yer alan verileri xjc tarafından oluşturulan Java sınıflarına nasıl yükleyebileceğimizi yakından inceleyelim. Tasit.dtd ye uyumlu bir Xml örneği aşağıda yer almaktadır:

<?xml version="1.0" encoding="ISO-8859-1"?>
<Tasit>
<araba>
<model>Ford Fiesta</model>
<motor>
<beygirgucu>75</beygirgucu>
<tipi>benzinli</tipi>
</motor>
</araba>

<araba>
<model>Opel Agila</model>
<motor>
<beygirgucu>70</beygirgucu>
<tipi>benzinli</tipi>
</motor>
</araba>
</Tasit>

Aşağıda yer alan program yardımı ile Xml dosyasında yer alan verileri elde edebiliriz:


package com.tasit;

import java.io.File;
import java.io.FileReader;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.EventFilter;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

import com.tasit.mapping.Araba;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception
	{
		XMLInputFactory xmlif = XMLInputFactory.newInstance();
		FileReader fr = new FileReader(new File("c:/temp/araba.xml"));
		XMLEventReader xmler = xmlif.createXMLEventReader(fr);
		EventFilter filter = new EventFilter() {
			public boolean accept(XMLEvent event) {
				return event.isStartElement();
			}
		};
		
		XMLEventReader xmlfer = xmlif.createFilteredReader(xmler, filter);
		StartElement e = (StartElement) xmlfer.nextEvent();
		
		
		JAXBContext ctx = JAXBContext.newInstance("com.tasit.mapping");
		Unmarshaller um = ctx.createUnmarshaller();

		while (xmlfer.peek() != null) 
		{
			Object o = um.unmarshal(xmler);
			if (o instanceof Araba) 
			{
				Araba araba = (Araba) o;
				System.out.println(araba.getModel());
				System.out.println(araba.getMotor().getBeygirgucu());
				System.out.println(araba.getMotor().getTipi());
				System.out.println("-----------------------------------");
			}
		}
		fr.close();

	}

}

Ekran çıktısı şu şekilde olacaktır:

Ford Fiesta
75
benzinli
-----------------------------------
Opel Agila
70
benzinli
-----------------------------------

Xml–>Java mapping işlemlerinin nasıl yapıldığını gördük. Aşağıdaki Java örneği Java–>Xml mapping işleminin nasıl yapıldığını göstermektedir.


package com.tasit;

import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import com.tasit.mapping.Araba;
import com.tasit.mapping.Motor;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception
	{
		
		Araba araba =  new Araba();
		Motor motor = new Motor();
		motor.setBeygirgucu("300");
		motor.setTipi("dizel");
		araba.setMotor(motor);
		araba.setModel("Crossfire");
		
		
		Marshaller marshaller = null;
		
		marshaller = JAXBContext.newInstance("com.tasit.mapping").createMarshaller();			
		marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, true );
		StringWriter writer =  new StringWriter();
		
		marshaller.marshal(araba, writer);
		
		System.out.println(writer.getBuffer().toString());

	}

}

Programı koşturduğumuzda ekran çıktısı şu şekilde olacaktır:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<araba>
    <model>Crossfire</model>
    <motor>
        <beygirgucu>300</beygirgucu>
        <tipi>dizel</tipi>
    </motor>
</araba>


EOF (End Of Fun)
Özcan Acar

JAXB ile Java-XML Mapping” hakkında bir yorum

Yorumlar kapalı.