1

我遇到了使用 jaxb 的 xml 问题。我希望能够生成这样的 xml 文件:

<Animals>
<Animal type="A">
    <name>aaaa</name>
    <j>text1</j>
 </Animal>
 <Animal type="A">
    <name>bbbb</name>
    <j>text3</j>
 </Animal>
 <Animal type="A">
    <name>cccc</name>
    <j>text5</j>
 </Animal>
<Animal type="B">
    <name>vvvvv</name>
    <i>3</i>
</Animal>
<Animal type="B">
    <name>ffff</name>
    <i>4</i>
</Animal>
<Animal type="B">
    <name>zzzz</name>
    <i>7</i>
</Animal>

这两种类型有一些相似的元素和一些特殊的元素。例如,j 是必需的,如果 type="A",则不应为 null;如果 type="B",则 i 是必需的,不应为 null。这可能吗?

这是动物类:

@XmlRootElement(name = "Animals")
@XmlAccessorType(XmlAccessType.FIELD)
 public class Animals {
@XmlElement(name="Animal")
private List<AnimalA> listA;
@XmlElement(name="Animal")
private List<AnimalB> listB;
//Getters and Setters
...
//Constructors
...

} 来测试它,这里是一个主要的功能:

public static void main(String[] args) {
    System.out.println("Starting here...");
    AnimalA a = new AnimalA("animalA", "valueA");
    AnimalB b = new AnimalB("animalB", "valueb",3);
    AnimalB b2 = new AnimalB("animalB2", "valueb2",56);
    List<AnimalA> listA = new ArrayList<AnimalA>();
    List<AnimalB> listB = new ArrayList<AnimalB>();
    listA.add(a);
    listB.add(b);
    listB.add(b2);
    Animals animals = new Animals(listA,listB);

    JAXBContext context = null;

    try {
        context = JAXBContext.newInstance(Animals.class);

        Marshaller m = context.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        if (animals != null) {
            m.marshal(animals, new File("C:\\animalz.xml"));
        }
    } catch (JAXBException e) {
        System.out.println(e);
    }

    Animals aa = null;
    URL url = null;
        try {

            url = new File("C:\\animalz.xml").toURI().toURL();
            Unmarshaller unmarshaller = context.createUnmarshaller();
            aa  = (Animals) unmarshaller.unmarshal(url);
            int countA = aa.getListA().size();
                   //               int countB = aa.getListB().size();
            System.out.println("size A==>"+countA);
                   //               System.out.println("size B ==>"+countB);
        } catch (JAXBException e) {
            System.out.println(e.getMessage());;
        } catch (MalformedURLException e) {
            System.out.println(e.getMessage());;
        }
}

这将返回: 从这里开始... size A==>3 如果我取消注释 CountB 的行,它会得到一个 NullPointerexception。

4

2 回答 2

0

注意: 我是EclipseLink JAXB (MOXy)负责人,也是JAXB (JSR-222)专家组的成员。

您可以使用 MOXy@XmlPath对此用例的扩展:

动物

import java.util.List;
import javax.xml.bind.annotation.*;    
import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement(name="Animals")
@XmlAccessorType(XmlAccessType.FIELD)
public class Animals {


    @XmlPath("Animal[@type='A']")
    private List<AnimalA> listA;

    @XmlPath("Animal[@type='B']")
    private List<AnimalB> listB;

}

演示

标准 JAXB 运行时 API 用于将 XML 转换为对象/从对象转换。

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Animals.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("input.xml");
        Animals animals = (Animals) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(animals, System.out);
    }

}

输入.xml/输出

<?xml version="1.0" encoding="UTF-8"?>
<Animals>
   <Animal type="A">
      <name>aaaa</name>
      <j>text1</j>
   </Animal>
   <Animal type="A">
      <name>bbbb</name>
      <j>text3</j>
   </Animal>
   <Animal type="A">
      <name>cccc</name>
      <j>text5</j>
   </Animal>
   <Animal type="B">
      <name>vvvvv</name>
      <i>3</i>
   </Animal>
   <Animal type="B">
      <name>ffff</name>
      <i>4</i>
   </Animal>
   <Animal type="B">
      <name>zzzz</name>
      <i>7</i>
   </Animal>
</Animals>

了解更多信息

于 2013-08-01T15:31:56.200 回答
0

认为你正在寻找的是这样的:

public class Animal {
    @XmlAttribute("type")
    private String type;

    @XmlElement(name="j", required=false)
    private String j;

    @XmlElement(name="i", required=false)
    private String i;

我不知道您有任何方法可以强制 A 类型始终具有 aj 元素。如果您需要这种程度的验证,我认为您将需要一个更烦人的结构:

<Animal_A>
    <j>asdf</j>
</Animal_A>
<Animal_B>
    <i>asdf</i>
</Animal_B>
于 2013-08-01T15:00:30.237 回答