使用JAXB处理设计不佳的XML [英] Dealing with poorly designed XML with JAXB
问题描述
我目前正在使用JAXB替换遗留系统,而且我在解析XML时遇到了问题。系统的首要要求是它必须是替代品,因此我无法修改XML的格式。以下是给我带来麻烦的XML部分。
I'm currently working on replacing a legacy system with JAXB and I'm running into problem with parsing the XML. The number one requirement of the system is that it must be a drop-in replacement so I cannot modify the format of the XML. Below is the XML section that is giving me trouble.
<xx>
<s1>
<X>-9999</X>
<Y>-9999</Y>
</s1>
<s2>
<X>-9999</X>
<Y>-9999</Y>
</s2>
</xx>
XML的问题是所有s#对象都是完全相同的并且可以存在最多256个。在JAXB中有一种方法可以注释这样的标记,还是我必须创建256个单独的注释?任何帮助都将非常受欢迎。
The issue with the XML is that all of the s# objects are the exact same and there can be up to 256 of them. Is there a way in JAXB to annotate such a tag or do I have to create 256 separate annotations? Any help would be most appreciated.
这是xx对象的java代码。注意:该对象最初编程时理解只有2个s#对象,但之后已经改变。
Here is the java code for the xx object. Note: the object was originally programmed with the understanding that there would only be 2 s# objects, but that since has changed.
@XmlRootElement(name="xx")
public class XMLXx implements Serializable {
private static final long serialVersionUID = 4064597372833234503L;
private XMLSite siteOne;
private XMLSite siteTwo;
@XmlElement(name="s1")
public XMLSite getSiteOne() {
return siteOne;
}
public void setSiteOne(XMLSite s1) {
this.siteOne = s1;
}
@XmlElement(name="s2")
public XMLSite getSiteTwo() {
return siteTwo;
}
public void setSiteTwo(XMLSite s2) {
this.siteTwo = s2;
}
}
这是XMLSite对象:
And here is the XMLSite object:
public class XMLSite implements Serializable {
private static final long serialVersionUID = -4374405403222014476L;
private Integer x;
private Integer y;
@XmlElement(name="X")
public Integer getX() {
return x;
}
public void setX(Integer x) {
this.x = x;
}
@XmlElement(name="Y")
public Integer getY() {
return y;
}
public void setY(Integer y) {
this.y = y;
}
}
推荐答案
如果您希望将 s#
项目作为集合处理:
If you want to handle at the s#
items as a collection:
import java.io.Serializable;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="xx")
public class XMLXx implements Serializable {
private static final long serialVersionUID = 4064597372833234503L;
private List<XMLSite> sites;
@XmlElement(name="s")
public List<XMLSite> getSites() {
return sites;
}
public void setSites(List<XMLSite> sites) {
this.sites = sites;
}
}
然后你可以做类似的事情愚弄JAXB认为所有元素( s1
, s2
等)实际上都被称为 s
:
Then you could do something like to fool JAXB into thinking all the elements (s1
, s2
, etc) are actually called s
:
import java.io.FileInputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(XMLXx.class);
XMLInputFactory xif = XMLInputFactory.newInstance();
XMLStreamReader xsr = xif.createXMLStreamReader(new FileInputStream("input.xml"));
xsr = new SiteStreamReaderDelegate(xsr);
Unmarshaller unmarshaller = jc.createUnmarshaller();
XMLXx object = (XMLXx) unmarshaller.unmarshal(xsr);
System.out.println(object.getSites().size());
}
private static class SiteStreamReaderDelegate extends StreamReaderDelegate {
public SiteStreamReaderDelegate(XMLStreamReader xsr) {
super(xsr);
}
@Override
public String getLocalName() {
String localName = super.getLocalName();
if(localName.startsWith("s")) {
return "s";
}
return localName;
}
}
}
类似的例子见:
- http://bdoughan.blogspot.com/2010/12/case-insensitive-unmarshalling.html
这篇关于使用JAXB处理设计不佳的XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!