[英]Unmarshal XML via JAXB
我有一个XML,如下所示:
<VisitorDataList>
<VisitorData>
<Attribute1List>
<Attribute1>
<Attribute1Name>name1</Attribute1Name>
<Attribute1Id>2</Attribute1Id>
</Attribute1>
<Attribute1>
<Attribute1Name>name1</Attribute1Name>
<Attribute1Id>3</Attribute1Id>
</Attribute1>
<Attribute1>
<Attribute1Name>name1</Attribute1Name>
<Attribute1Id>1</Attribute1Id>
</Attribute1>
</Attribute1List>
<Attribute2List>
<Attribute2>
<Attribute2Name>name2</Attribute2Name>
<Attribute2Id>113</Attribute2Id>
</Attribute2>
<Attribute2>
<Attribute2Name>name2</Attribute2Name>
<Attribute2Id>115</Attribute2Id>
</Attribute2>
<Attribute2>
<Attribute2Name>name2</Attribute2Name>
<Attribute2Id>114</Attribute2Id>
</Attribute2>
</Attribute2List>
</VisitorData>
</VisitorDataList>
Attribute1List
和Attribute2List
名称和值都是动态的,因此它们可以是Attribute3List
或Attribute4List
等。 现在,我想通过jAXB解析此xml,java bean类似于:
@XmlRootElement(name = "VisitorDataList")
public class VisitorDataList {
@XmlElement(name = "VisitorData")
public List<Visitor> getVisitors() {
return visitors;
}
public void setVisitors(List<Visitor> visitors) {
this.visitors = visitors;
}
}
public class Visitor {
private List<String> attributes= new ArrayList<String>();
public List<String> getAttributes() {
return attributes;
}
public void setAttributes(List<String> attributes) {
this.attributes= attributes;
}
}
我的问题是如何将所有属性名称映射到一个列表中? 提前致谢。
您可以使用JAXB通过StreamReaderDelegate从StAX解组,以从元素名称中剥离数字。 然后将JAXB映射到元素
以下是我写的文章的链接,在其中我使用这种方法进行不区分大小写的编组:
VistorDataList
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement(name = "VisitorDataList")
public class VisitorDataList {
private List<Visitor> visitors;
@XmlElementWrapper(name="VisitorData")
@XmlElement(name = "AttributeList")
public List<Visitor> getVisitors() {
return visitors;
}
public void setVisitors(List<Visitor> visitors) {
this.visitors = visitors;
}
}
游客
import java.util.*;
import javax.xml.bind.annotation.XmlElement;
public class Visitor {
private List<String> attributes = new ArrayList<String>();
@XmlElement(name="AttributeName")
public List<String> getAttributes() {
return attributes;
}
public void setAttributes(List<String> attributes) {
this.attributes = attributes;
}
}
演示
import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.stream.util.StreamReaderDelegate;
import javax.xml.transform.stream.StreamSource;
public class Demo {
public static void main(String[] args) throws Exception {
XMLInputFactory xif = XMLInputFactory.newFactory();
StreamSource xml = new StreamSource("src/forum18071557/input.xml");
XMLStreamReader xsr = xif.createXMLStreamReader(xml);
xsr = new StreamReaderDelegate(xsr) {
@Override
public String getLocalName() {
String localName = super.getLocalName();
if(localName.startsWith("Attribute") && localName.endsWith("List")) {
return "AttributeList";
} else if(localName.startsWith("Attribute") && localName.endsWith("Name")) {
return "AttributeName";
} else if(localName.startsWith("Attribute")) {
return "ignore";
} else {
return localName;
}
}
};
xsr = xif.createFilteredReader(xsr, new StreamFilter() {
@Override
public boolean accept(XMLStreamReader reader) {
if(reader.isStartElement() || reader.isEndElement()) {
return !reader.getLocalName().equals("ignore");
} else {
return true;
}
}
});
JAXBContext jc = JAXBContext.newInstance(VisitorDataList.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
VisitorDataList vdl = (VisitorDataList) unmarshaller.unmarshal(xsr);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(vdl, System.out);
}
}
产量
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<VisitorDataList>
<VisitorData>
<AttributeList>
<AttributeName>name1</AttributeName>
<AttributeName>name1</AttributeName>
<AttributeName>name1</AttributeName>
</AttributeList>
<AttributeList>
<AttributeName>name2</AttributeName>
<AttributeName>name2</AttributeName>
<AttributeName>name2</AttributeName>
</AttributeList>
</VisitorData>
</VisitorDataList>
我尝试使用JAXB解封XML文件,但只能静态解析它。您可以尝试一次。
visitor.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<VisitorDataList>
<VisitorData>
<AttributeList>
<Attribute>
<AttributeName>name1</AttributeName>
<AttributeId>2</AttributeId>
</Attribute>
<Attribute>
<AttributeName>name1</AttributeName>
<AttributeId>3</AttributeId>
</Attribute>
<Attribute>
<AttributeName>name1</AttributeName>
<AttributeId>1</AttributeId>
</Attribute>
</AttributeList>
<AttributeList>
<Attribute>
<AttributeName>name2</AttributeName>
<AttributeId>113</AttributeId>
</Attribute>
<Attribute>
<AttributeName>name2</AttributeName>
<AttributeId>115</AttributeId>
</Attribute>
<Attribute>
<AttributeName>name2</AttributeName>
<AttributeId>114</AttributeId>
</Attribute>
</AttributeList>
</VisitorData>
visitordatalist.java
package foo.bar.me.too;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="VisitorDataList")
public class visitordatalist {
List<visitordata> vstd;
@XmlElement(name="VisitorData")
public List<visitordata> getVstd() {
return vstd;
}
public void setVstd(List<visitordata> vstd) {
this.vstd = vstd;
}
}
visitordata.java
package foo.bar.me.too;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
public class visitordata {
List<attributelist> atrl;
public String toString() {
return atrl.toString();
}
@XmlElement(name="AttributeList")
public List<attributelist> getAtrl() {
return atrl;
}
public void setAtrl(List<attributelist> atrl) {
this.atrl = atrl;
}
}
attributelist.java
package foo.bar.me.too;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
public class attributelist {
List<attribute> atr;
public String toString() {
return atr.toString();
}
@XmlElement(name="Attribute")
public List<attribute> getAtr() {
return atr;
}
public void setAtr(List<attribute> atr) {
this.atr = atr;
}
}
attribute.java
package foo.bar.me.too;
import javax.xml.bind.annotation.XmlElement;
public class attribute {
String atrName;
String atrId;
public String toString() {
return atrName+" "+atrId;
}
@XmlElement(name="AttributeName")
public String getAtrName() {
return atrName;
}
public void setAtrName(String atrName) {
this.atrName = atrName;
}
@XmlElement(name="AttributeId")
public String getAtrId() {
return atrId;
}
public void setAtrId(String atrId) {
this.atrId = atrId;
}
}
JAXBExample.java
package foo.bar.me.too;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
public class JAXBExample {
public static void main(String[] args) {
try {
File file = new File("visitor.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(visitordatalist.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
visitordatalist vstdl = (visitordatalist) jaxbUnmarshaller.unmarshal(file);
System.out.println(vstdl.getVstd());
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
对于某些特殊的JAXB实现,有一种特殊的奥术知识。 例如,对于FasterXML(在WildFly中使用),您应该更改一个属性以使其起作用(只需重写Delegator中的其他方法):
@Override
public Object getProperty(String name) {
Object property = super.getProperty(name);
if("org.codehaus.stax2.internNames".equals(name)) {
return Boolean.FALSE;
}
return property;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.