我有一个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;
}
}
我的问题是如何将所有属性名称映射到一个列表中?提前谢谢。
答案 0 :(得分:1)
您可以使用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>
答案 1 :(得分:0)
我尝试使用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();
}
}
}
答案 2 :(得分:0)
对于某些特殊的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;
}