定义具有相同名称的XML元素

时间:2013-08-01 13:54:50

标签: java xml jaxb

我使用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,并且i是必需的,如果type =“B”则不应为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());;
        }
}

返回: 从这里开始...... 尺寸A ==&gt; 3 如果我取消注释CountB的行,它会得到一个NullPointerexception。

2 个答案:

答案 0 :(得分: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 总是有一个j元素。如果你需要这种程度的验证,我认为你需要一个更烦人的结构:

<Animal_A>
    <j>asdf</j>
</Animal_A>
<Animal_B>
    <i>asdf</i>
</Animal_B>

答案 1 :(得分: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);
    }

}

<强> input.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>

了解更多信息