`
liugang594
  • 浏览: 987495 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JAXB中怎么构建对父对象的链接

 
阅读更多

还是以在第一节介绍JAXB的schema为例:

<?xml version="1.0" encoding="UTF-8"?>  
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.liulutu.com/students/"  
    targetNamespace="http://www.liulutu.com/students/">  
    <element name="students">  
        <complexType>  
            <sequence>  
                <element name="student" type="tns:StudentType" maxOccurs="unbounded" />  
            </sequence>  
        </complexType>  
    </element>  
    <simpleType name="SexType">  
        <restriction base="string">  
            <enumeration value="Male"></enumeration>  
            <enumeration value="Female"></enumeration>  
        </restriction>  
    </simpleType>  
  
    <complexType name="StudentType">  
        <attribute name="sex" type="tns:SexType"></attribute>  
        <attribute name="name" type="string"></attribute>  
    </complexType>  
</schema>  

 生成的类文件如下:

 

models

从Schema定义里可以看出,Students里包含有多个StudentType对象:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "student"
})
@XmlRootElement(name = "students")
public class Students {

    @XmlElement(required = true)
    protected List<StudentType> student;

    /**
     * Gets the value of the student 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 student property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getStudent().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link StudentType }
     * 
     * 
     */
    public List<StudentType> getStudent() {
        if (student == null) {
            student = new ArrayList<StudentType>();
        }
        return this.student;
    }

}

现在的问题是,从StudentType对象里,怎么能访问到它的父对象也就是上面的students对象呢?StudentType类如下:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "StudentType")
public class StudentType {

    @XmlAttribute(name = "sex")
    protected SexType sex;
    @XmlAttribute(name = "name")
    protected String name;
    @XmlAttribute(name = "birthday")
    @XmlJavaTypeAdapter(Adapter1 .class)
    @XmlSchemaType(name = "date")
    protected Calendar birthday;

    /**
     * Gets the value of the sex property.
     * 
     * @return
     *     possible object is
     *     {@link SexType }
     *     
     */
    public SexType getSex() {
        return sex;
    }

    /**
     * Sets the value of the sex property.
     * 
     * @param value
     *     allowed object is
     *     {@link SexType }
     *     
     */
    public void setSex(SexType value) {
        this.sex = value;
    }

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

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

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

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

}

从类定义可以看出,其中没有任何描述Students对象的信息。

解决方法:

首先,假设要解析的文件内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:students xmlns:ns2="http://www.liulutu.com/students/">
	<student sex="Female" name="Bob" birthday="2003-11-27+08:00" />
	<student sex="Male" name="Lisa" birthday="2003-10-26+08:00" />
</ns2:students>

(如果手头没有文件,也可以用以上模型快速的生成一个,例如:)

		StudentType studentType = new StudentType();
		studentType.setBirthday(Calendar.getInstance());
		studentType.setName("Bob");
		studentType.setSex(SexType.FEMALE);

		Students students = new Students();
		students.getStudent().add(studentType);

		JAXBContext context = JAXBContext.newInstance(Students.class);
		Marshaller marshaller = context.createMarshaller();
		marshaller.marshal(students, new File("a.xml")); 

方法一:使用afterUnmarshal(Unmarshaller u, Object parent)方法

首先修改一下StudentType类,增加一个用来存取父对象的变量:

	private Students parent;
	
	public Students getParent() {
		return parent;
	}

因为模型是由JAXB直接读取和生成的,因此我们不能通过简单的setParent()来设置parent对象。

 

可以在生成的模型类中添加一个public void afterUnmarshal(Unmarshaller u, Object parent) 方法,这个方法在每次构建完模型后都会调用(甚至我们什么接口实现,类继承都不需要声明就会自动调用),其中的parent参数就是我们期望的父模型对象,因此可以直接把这个parent对象设置成我们期望的parent对象:

	public void afterUnmarshal(Unmarshaller u, Object parent) {
		if (parent instanceof Students) {
			this.parent = (Students)parent;
		}
	}

可以检验一下:

		JAXBContext context = JAXBContext.newInstance(Students.class);
		Unmarshaller unmarshaller = context.createUnmarshaller();
		Students students = (Students) unmarshaller.unmarshal(new File("a.xml"));
		List<StudentType> student = students.getStudent();
		for(StudentType st: student){
			System.out.println(st.getName());
			System.out.println(st.getParent());
		}

方法二:使用Binder

方法一简单易用,但是缺点就是需要修改模型,这里介绍的方法就不需要修改模型,只是在读取的时候需要有点不一样:

首先我们用普通的Dom方式读取文件内容:

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setNamespaceAware(true);
		Document document = factory.newDocumentBuilder().parse(new File("a.xml"));

然后创建JAXBContext对象和Binder对象:

		JAXBContext context = JAXBContext.newInstance(Students.class);
		Binder<Node> binder = context.createBinder();

最后用Binder对象去解析模型的和链接父子关系:

		Students students = (Students) binder.updateJAXB(document.getDocumentElement());
		List<StudentType> student = students.getStudent();
		for(StudentType st: student){
			System.out.println(st.getName());
			Node xmlNode = binder.getXMLNode(st);
			Object parent = binder.getJAXBNode(xmlNode.getParentNode());
			System.out.println(parent);
		}

方法三 使用Unmarshall.Listener监听

除了以上两种方法,还可以使用监听的方式,在marshall的过程中构建父子关系,有点类似于方法一

		JAXBContext context = JAXBContext.newInstance(Students.class);
		Unmarshaller unmarshaller = context.createUnmarshaller();
		
		final Map<StudentType, Students> map = new HashMap<StudentType, Students>();
		unmarshaller.setListener(new Listener() {
			public void afterUnmarshal(Object target, Object parent) {
				super.afterUnmarshal(target, parent);
				if(target instanceof StudentType && parent instanceof Students){
					map.put((StudentType)target, (Students) parent);
				}
				
			}
		});
		Students students = (Students) unmarshaller.unmarshal(new File("a.xml"));
		List<StudentType> student = students.getStudent();
		for(StudentType st: student){
			System.out.println(st.getName());
			System.out.println(map.get(st));
		}

 

分享到:
评论

相关推荐

    JAXB工具类 xml转为java对象 java对象转为xml

    Java Architecture for XML Binding (JAXB) 是Java平台中用于处理XML和Java对象之间转换的一个标准API。它使得在Java应用程序中使用XML数据变得更加方便,无需手动编写大量的转换代码。本教程将详细介绍JAXB如何实现...

    JAXB技术实现xml与java对象互相转化代码教程

    JDK中JAXB相关的重要Class和Interface:(来源于百度百科JAXB) •JAXBContext类,是应用的入口,用于管理XML/Java绑定信息。 •Marshaller接口,将Java对象序列化为XML数据。 •Unmarshaller接口,将XML数据反序列...

    通过JAXB实现完成java对象和xml的互相转换

    无论是序列化Java对象为XML,还是从XML数据中构建Java对象,JAXB都提供了高效且易于使用的API。在实际开发中,配合良好的设计模式,JAXB能够帮助我们更好地管理和操作XML数据。通过实践和学习,开发者可以充分利用...

    用jaxb自动生成xsd对像

    在Java世界中,Java Architecture for XML Binding (JAXB) 是一个强大的工具,用于处理XML文档和Java对象之间的转换。当你需要在XML与Java类之间进行数据交换时,JAXB提供了一种自动化的机制,可以将XML Schema (XSD...

    idea 中用jaxb 读xml中数据

    3. **创建Unmarshaller对象**:JAXB API中的Unmarshaller类负责将XML数据解码为Java对象。我们需要实例化一个Unmarshaller对象,并指定要解析的XML文件。 ```java File file = new File("path_to_your_xml_file.xml...

    用jaxb 实现 xml转java对象技术

    **XML到Java对象转换技术——基于JAXB** 在软件开发中,XML作为一种数据交换格式,广泛用于不同系统间的数据传输。然而,面对大量的XML数据,手动解析和转换为Java对象显得繁琐且效率低下。这时,Java Architecture...

    JAXB xml与对象转换

    Java Architecture for XML Binding (JAXB) 是Java平台上的一个标准技术,用于在XML文档和Java对象之间进行数据绑定。它允许开发者将XML Schema定义的数据结构直接映射到Java类,从而方便地在XML和Java对象之间进行...

    JAXB的 eclipse插件

    这个插件允许开发者在Eclipse中方便地进行JAXB相关的开发工作,比如生成Java类从XML Schema,或者将Java对象转换为XML。 在Java世界中,JAXB扮演着核心角色,特别是在处理XML数据时。它使得Java程序能够方便地序列...

    webservice之使用jaxb把xml转换Object或把对象转换成xml文件

    在Java世界中,使用JAXB(Java Architecture for XML Binding)库可以方便地实现XML数据与Java对象之间的转换,从而在WebService中轻松处理数据交换。本篇文章将深入探讨如何使用JAXB进行XML到Object以及Object到XML...

    JAXB完成XML和Java对象的互转

    该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用...

    JAXB2 jaxb-api.jar jaxb-xjc.jar jaxb-impl.jar activation.jar

    在JAXB中,它主要用于支持JavaMail和JAF相关的功能,例如处理SOAP消息,因为SOAP消息通常涉及MIME编码。 在解压这个压缩包后,你会在lib文件夹下找到这些jar文件。如果在你的项目中需要使用JAXB2来处理XML,你可以...

    JAXB乱码问题解决

    在Java开发中,JAXB(Java Architecture for XML Binding)是一个用于将XML文档和Java对象之间进行绑定的技术。在处理XML文件时,特别是涉及到序列化和反序列化时,可能会遇到字符编码问题,即所谓的“乱码”。这个...

    JAXB的安装包及插件

    **JAXB(Java Architecture for XML Binding)** 是Java平台中用于XML到Java对象绑定的API,它是Java EE和Java SE标准的一部分,允许开发者在Java应用程序中方便地将XML数据转换为Java对象,反之亦然。这个过程极大...

    jaxb-api jaxb-impl jar

    JAXB允许开发者将XML文档转换为可以直接在Java应用程序中使用的对象,同时也能够将Java对象转换为XML格式的数据。这在处理XML数据时极大地提高了效率和便利性。 `jaxb-api`和`jaxb-impl`是JAXB框架的核心组成部分。...

    jaxb解析xml为对象例子

    在"jaxb解析xml为对象例子"中,我们将探讨如何使用JAXB将XML文件解析为Java对象。首先,我们需要一个XML文件,它包含我们想要映射到Java对象的数据。例如,假设我们有一个名为`employee.xml`的文件,其中包含员工...

    利用jaxb实现xml和bean互转

    在JAXB中,这些Bean类会被映射到XML元素和属性。 2. **XML Schema**: 定义了XML文档的结构和数据类型的规范。JAXB可以基于XML Schema自动生成Java Bean类,或者将Java Bean类转换为XML Schema。 3. **Marshalling*...

    javax.rar(jaxb-impl-2.3.0、jaxb-core-2.3.0、jaxb-api-2.3.0)

    在描述中提到的“Maven项目中缺少jaxb-api的异常报错”,通常指的是在运行或构建Maven项目时,由于缺少`jaxb-api-2.3.0.jar`依赖导致的错误。 JAXB(Java Architecture for XML Binding)是Java SE的一部分,它允许...

    jaxb-ri-2.2.7

    2. **二进制库**:包含JAXB运行时库的JAR文件(如`lib/jaxb-ri-runtime.jar`),这些库文件可以在Java项目中作为依赖引入,实现XML到Java对象的自动映射。 3. **源代码**:如果包含源码(如`src`目录),开发者可以...

    使用maven、jaxb等技术构建可配置编译打包及可配置项目运行

    接下来,JAXB(Java Architecture for XML Binding)是Java中用于XML数据绑定的规范,它可以将XML文档映射为Java对象,反之亦然。在项目中,我们可以使用JAXB来生成Java类,这些类可以直接与XML配置文件交互。为了...

Global site tag (gtag.js) - Google Analytics