使用 JAXB 的具有属性和内容的 XML 元素

Posted

技术标签:

【中文标题】使用 JAXB 的具有属性和内容的 XML 元素【英文标题】:XML element with attribute and content using JAXB 【发布时间】:2011-07-27 18:00:43 【问题描述】:

如何使用 JAXB 生成以下 XML?

<sport type="" gender="">
    sport description
</sport>

【问题讨论】:

【参考方案1】:

@XmlAttribute注释类型和性别属性,用@XmlValue注释描述属性:

package org.example.sport;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Sport 

    @XmlAttribute
    protected String type;

    @XmlAttribute
    protected String gender;

    @XmlValue;
    protected String description;


更多信息

http://bdoughan.blogspot.com/2011/06/jaxb-and-complex-types-with-simple.html

【讨论】:

【参考方案2】:

正确的方案应该是:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.example.org/Sport"
xmlns:tns="http://www.example.org/Sport" 
elementFormDefault="qualified"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
jaxb:version="2.0">

<complexType name="sportType">
    <simpleContent>
        <extension base="string">
            <attribute name="type" type="string" />
            <attribute name="gender" type="string" />
        </extension>
    </simpleContent>
</complexType>

<element name="sports">
    <complexType>
        <sequence>
            <element name="sport" minOccurs="0" maxOccurs="unbounded"
                type="tns:sportType" />
        </sequence>
    </complexType>
</element>

为 SportType 生成的代码将是:

package org.example.sport;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "sportType")
public class SportType 
    @XmlValue
    protected String value;
    @XmlAttribute
    protected String type;
    @XmlAttribute
    protected String gender;

    public String getValue() 
        return value;
    

    public void setValue(String value) 
        this.value = value;
    

    public String getType() 
    return type;
    


    public void setType(String value) 
        this.type = value;
    

    public String getGender() 
        return gender;
    

    public void setGender(String value) 
        this.gender = value;
    

【讨论】:

【参考方案3】:

这是可行的解决方案:

输出:

public class XmlTest 

    private static final Logger log = LoggerFactory.getLogger(XmlTest.class);

    @Test
    public void createDefaultBook() throws JAXBException 
        JAXBContext jaxbContext = JAXBContext.newInstance(Book.class);
        Marshaller marshaller = jaxbContext.createMarshaller();

        StringWriter writer = new StringWriter();
        marshaller.marshal(new Book(), writer);

        log.debug("Book xml:\n ", writer.toString());
    


    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name = "book")
    public static class Book 

        @XmlElementRef(name = "price")
        private Price price = new Price();


    

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name = "price")
    public static class Price 
        @XmlAttribute(name = "drawable")
        private Boolean drawable = true; //you may want to set default value here

        @XmlValue
        private int priceValue = 1234;

        public Boolean getDrawable() 
            return drawable;
        

        public void setDrawable(Boolean drawable) 
            this.drawable = drawable;
        

        public int getPriceValue() 
            return priceValue;
        

        public void setPriceValue(int priceValue) 
            this.priceValue = priceValue;
        
    

输出:

22:00:18.471 [main] 调试 com.grebski.stack.XmlTest - Book xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<book>
    <price drawable="true">1234</price>
</book>

【讨论】:

只是想添加一个类似答案的链接,以帮助那些将其视为解决方案的人。好答案,顺便说一句。 ***.com/a/15429363/1686575 你救我! :D 我使用@XmlValue 解决了【参考方案4】:

更新的解决方案 - 使用我们正在讨论的架构解决方案。这会让你得到答案:

示例架构:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.example.org/Sport"
xmlns:tns="http://www.example.org/Sport" 
elementFormDefault="qualified"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
jaxb:version="2.0">

<complexType name="sportType">
    <attribute name="type" type="string" />
    <attribute name="gender" type="string" />
</complexType>

<element name="sports">
    <complexType>
        <sequence>
            <element name="sport" minOccurs="0" maxOccurs="unbounded"
                type="tns:sportType" />
        </sequence>
    </complexType>
</element>

生成的代码

运动类型:

package org.example.sport; 

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "sportType")
public class SportType 

    @XmlAttribute
    protected String type;
    @XmlAttribute
    protected String gender;

    public String getType() 
        return type;
    


    public void setType(String value) 
        this.type = value;
    

    public String getGender() 
        return gender;
    

    public void setGender(String value) 
        this.gender = value;
    


运动:

package org.example.sport;

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 = 
        "sport"
)
@XmlRootElement(name = "sports")
public class Sports 

    protected List<SportType> sport;

    public List<SportType> getSport() 
        if (sport == null) 
            sport = new ArrayList<SportType>();
        
        return this.sport;
    


通过在命令行上针对模式运行 xjc 来生成输出类文件

【讨论】:

不使用 XSD。使用 JAXB 注释。 当然可以,但是您可以生成一个非常简单的 XSD 来描述上述 XML 结构,从而为您生成带有注释的 Java 代码文件。或者,您可以手动构建它们,注释结构应该在文档中。使用 XSD 的优点是可以非常快速地更改结构并重新生成 java 代码文件。这取决于你对这两种方法的舒适程度download.oracle.com/javaee/5/tutorial/doc/bnbah.html 感谢您的回复。但我的问题是如何手动使用注释生成给定的 XML。我需要如何定义我的实体类文件? 在上面看到我的新解决方案,真的希望这会有所帮助

以上是关于使用 JAXB 的具有属性和内容的 XML 元素的主要内容,如果未能解决你的问题,请参考以下文章

Xml Jaxb 命名空间和属性顺序

XML解析器(Unmarshal)使用JaxB从xml文件中获取元素

Java:使用JAXB的注解实现定制xml结果

JAXB XML;如何在不需要创建元素的 pojo 的情况下获取元素的属性?

通过JAXB完成Java对象与XML之间的转换

使用 xslt 2.0 合并具有相同父属性值的元素的 xml 内容