gpt4 book ai didi

java - 困难的 JAXB 映射

转载 作者:行者123 更新时间:2023-11-29 08:07:35 24 4
gpt4 key购买 nike

我正在尝试在更大的文档中映射以下 XML 结构,显然这不是 XML 的最大用途,但这是我必须处理的。

为清楚起见简化的示例:

  <details>
<pictures>
<picture1>
http://domain.com/path/picture1.jpg
</picture1>
<picture2>
http://domain.com/path/picture2.jpg
</picture2>
<picture3>
http://domain.com/path/picture3.jpg
</picture3>
<picture4>
http://domain.com/path/picture4.jpg
</picture4>
<picture5>
http://domain.com/path/picture5.jpg
</picture5>
<picture6>
http://domain.com/path/picture6.jpg
</picture6>
<picture7>
http://domain.com/path/picture7.jpg
</picture7>
</pictures>
</details>

此文档有一个 DTD,它声明将有多达 30 个不同的图片元素,编号为 1-30,名称为 <picutre[n]/>

我想做的是,而不是为这些称为 Picture1、Picture2、Picture3 等的每个元素创建 30 个不同的类。我只想使用一个图片类并将其用于所有 30 个唯一元素名称。

以下是我到目前为止尝试过的方法。

@XmlRootElement
public class Details {

...

@XmlElementWrapper
@XmlElementRefs({
@XmlElementRef( name="picture1", type=Picture.class ),
@XmlElementRef( name="picture2", type=Picture.class ),
@XmlElementRef( name="picture3", type=Picture.class ),
@XmlElementRef( name="picture4", type=Picture.class ),
@XmlElementRef( name="picture5", type=Picture.class ),
@XmlElementRef( name="picture6", type=Picture.class ),
@XmlElementRef( name="picture7", type=Picture.class ),
@XmlElementRef( name="picture8", type=Picture.class ),
@XmlElementRef( name="picture9", type=Picture.class ),
@XmlElementRef( name="picture10", type=Picture.class ),
@XmlElementRef( name="picture11", type=Picture.class ),
@XmlElementRef( name="picture12", type=Picture.class ),
@XmlElementRef( name="picture13", type=Picture.class ),
@XmlElementRef( name="picture14", type=Picture.class ),
@XmlElementRef( name="picture15", type=Picture.class ),
@XmlElementRef( name="picture16", type=Picture.class ),
@XmlElementRef( name="picture17", type=Picture.class ),
@XmlElementRef( name="picture18", type=Picture.class ),
@XmlElementRef( name="picture19", type=Picture.class ),
@XmlElementRef( name="picture20", type=Picture.class ),
@XmlElementRef( name="picture21", type=Picture.class ),
@XmlElementRef( name="picture22", type=Picture.class ),
@XmlElementRef( name="picture23", type=Picture.class ),
@XmlElementRef( name="picture24", type=Picture.class ),
@XmlElementRef( name="picture25", type=Picture.class ),
@XmlElementRef( name="picture26", type=Picture.class ),
@XmlElementRef( name="picture27", type=Picture.class ),
@XmlElementRef( name="picture28", type=Picture.class ),
@XmlElementRef( name="picture29", type=Picture.class ),
@XmlElementRef( name="picture30", type=Picture.class )
})
public List<Picture> getPictures() {
return this.pictures;
}

public void setPictures( List<Pictures> pictures ) {
this.pictures = pictures;
}

...

}

@XmlElementWrapper
public class Picture {
...
}

这会导致 getPictures 始终返回 null。

此外,我尝试将 Picture 类上的注释更改为 @XmlElementWrapper( name="picture1" )这导致我得到一个从 getPictures() 返回的列表,但只包含 <picture1/>元素,而不是其余部分。

我知道我可以求助于获取 JAXBElement 对象的列表,但如果可以避免,我宁愿不这样做。有什么想法可以映射吗?

最佳答案

有几种方法可以处理这个用例:

选项#1

您可以利用 @XmlElements 执行以下操作:

package forum10109418;

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Details {

private List<Picture> pictures;

@XmlElementWrapper
@XmlElements({
@XmlElement( name="picture1", type=Picture.class ),
@XmlElement( name="picture2", type=Picture.class ),
@XmlElement( name="picture3", type=Picture.class ),
@XmlElement( name="picture4", type=Picture.class ),
@XmlElement( name="picture5", type=Picture.class ),
@XmlElement( name="picture6", type=Picture.class ),
@XmlElement( name="picture7", type=Picture.class ),
@XmlElement( name="picture8", type=Picture.class ),
@XmlElement( name="picture9", type=Picture.class ),
@XmlElement( name="picture10", type=Picture.class ),
@XmlElement( name="picture11", type=Picture.class ),
@XmlElement( name="picture12", type=Picture.class ),
@XmlElement( name="picture13", type=Picture.class ),
@XmlElement( name="picture14", type=Picture.class ),
@XmlElement( name="picture15", type=Picture.class ),
@XmlElement( name="picture16", type=Picture.class ),
@XmlElement( name="picture17", type=Picture.class ),
@XmlElement( name="picture18", type=Picture.class ),
@XmlElement( name="picture19", type=Picture.class ),
@XmlElement( name="picture20", type=Picture.class ),
@XmlElement( name="picture21", type=Picture.class ),
@XmlElement( name="picture22", type=Picture.class ),
@XmlElement( name="picture23", type=Picture.class ),
@XmlElement( name="picture24", type=Picture.class ),
@XmlElement( name="picture25", type=Picture.class ),
@XmlElement( name="picture26", type=Picture.class ),
@XmlElement( name="picture27", type=Picture.class ),
@XmlElement( name="picture28", type=Picture.class ),
@XmlElement( name="picture29", type=Picture.class ),
@XmlElement( name="picture30", type=Picture.class )
})

public List<Picture> getPictures() {
return this.pictures;
}

public void setPictures( List<Picture> pictures ) {
this.pictures = pictures;
}

}

选项#2

您可以按如下方式映射您的Details 类:

package forum10109418;

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Details {

private List<Picture> pictures;

@XmlElementWrapper
@XmlElement(name="picture")
public List<Picture> getPictures() {
return this.pictures;
}

public void setPictures( List<Picture> pictures ) {
this.pictures = pictures;
}

}

然后使用 StreamReaderDelegate 来切断数字后缀:

package forum10109418;

import java.io.FileInputStream;
import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.stream.util.StreamReaderDelegate;

public class Demo {

public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Details.class);

XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xsr = xif.createXMLStreamReader(new FileInputStream("src/forum10109418/input.xml"));
xsr = new StreamReaderDelegate(xsr) {
@Override
public String getLocalName() {
String localName = super.getLocalName();
if(localName.startsWith("picture") && !localName.equals("pictures")) {
return "picture";
}
return localName;
}

};
Unmarshaller unmarshaller = jc.createUnmarshaller();
Details details = (Details) unmarshaller.unmarshal(xsr);
System.out.println(details.getPictures().size());
}

}

选项 #3

如果您使用 EclipseLink MOXy作为你的JAXB (JSR-222)提供程序,那么您可以使用我们添加的 @XmlVariableNode 扩展:

关于java - 困难的 JAXB 映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10109418/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com