我使用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。
答案 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>
了解更多信息