问题
I have an XML as bellow.
<hotelRoomDetails>
<NightRates>
<Night1>67</Night1>
<Night2>67.5</Night2>
........
........
<Night25>65</Night25>
</NightRates>
.......
</hotelRoomDetails>
The element Night1,Night2,Night3 are always dynamic, and this count may vary from 1 to 35 times. Parent tag <NightRates>
is always consistent.
The element <Night1>
, <Night2>
.. are not having any other attribute. It gives information about the hotel rate per night.
I want to create a 'LinkedList'(to preserve order) which contains the rate information of individual night. How can I handle this situation without knowing the occurrence count of element? How to create java class for this xml?
回答1:
Unmarshal Only
If you are just doing unmarshalling then you can use a StreamReaderDelegate
to strip off the numeric suffix.
Demo
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 {
JAXBContext jc = JAXBContext.newInstance(HotelRoomDetails.class);
XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource("src/forum19834756/input.xml"));
xsr = new StreamReaderDelegate(xsr) {
@Override
public String getLocalName() {
String localName = super.getLocalName();
if(localName.startsWith("Night") && !localName.equals("NightRates")) {
return "Night";
}
return localName;
}
};
Unmarshaller unmarshaller = jc.createUnmarshaller();
HotelRoomDetails details = (HotelRoomDetails) unmarshaller.unmarshal(xsr);
System.out.println(details.getNightRates().size());
}
}
HotelRoomDetails
Then you have a collection property that maps to the element called Night
.
import java.util.*;
import javax.xml.bind.annotation.*;
@XmlRootElement
public class HotelRoomDetails {
private List<String> nightRates = new ArrayList<String>();
@XmlElementWrapper(name = "NightRates")
@XmlElement(name = "Night")
public List<String> getNightRates() {
return nightRates;
}
}
Unmarshal & Marshal
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
If you need to support reading and writing to this format you could use MOXy's @XmlVariableNode
extension.
- http://blog.bdoughan.com/2013/06/mapping-bad-xml-enumerated-collection.html
回答2:
You can make NightRates field of type any. And work with its content through org.w3c.dom.Element:
@XmlAnyElement
protected Element NightRates;
来源:https://stackoverflow.com/questions/19834756/jaxb-unmarshalling-with-dynamic-elements