Skip to content

Instantly share code, notes, and snippets.

@dalelane
Created July 3, 2014 11:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dalelane/983f278d2485d29a6ef4 to your computer and use it in GitHub Desktop.
Save dalelane/983f278d2485d29a6ef4 to your computer and use it in GitHub Desktop.
JAXB solution - a solution to my problem with https://gist.github.com/dalelane/88df784c3cb74b214d5c - using JAXB to unmarshall fragments of XML from an XMLStreamReader
package sandbox;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
public class JaxbProblem {
// five items in XML fragments
private static final String TEST1_STR = "<test key=\"one\"></test>";
private static final String TEST2_STR = "<test key=\"two\"></test>";
private static final String TEST3_STR = "<test key=\"three\"></test>";
private static final String TEST4_STR = "<test key=\"four\"></test>";
private static final String TEST5_STR = "<test key=\"five\"></test>";
// combine the five items into XML documents - with and without whitespace in between
private static final String XML_WITH_SPACES =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<jaxbissue>" +
TEST1_STR + " " + TEST2_STR + " " + TEST3_STR + " " + TEST4_STR + " " + TEST5_STR + " " +
"</jaxbissue>";
private static final String XML_WITHOUT_SPACES =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<jaxbissue>" +
TEST1_STR + TEST2_STR + TEST3_STR + TEST4_STR + TEST5_STR +
"</jaxbissue>";
public static void main(String[] args)
{
String[] tests = { XML_WITH_SPACES, XML_WITHOUT_SPACES };
for (String test : tests){
System.out.println("About to process a new XML document...");
try {
// prepare a stream to read the XML document
InputStream stream = new ByteArrayInputStream(test.getBytes());
XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(stream);
// prepare an unmarshaller to turn the XML into objects
JAXBContext context = JAXBContext.newInstance(Test.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
// get first event for the XML parsing
int readerEvent = reader.next();
// keep going until we reach the end of the document
while (readerEvent != XMLStreamConstants.END_DOCUMENT){
// keep unmarshalling for every element of the expected type
while (readerEvent == XMLStreamConstants.START_ELEMENT && reader.getLocalName().equals(Test.XMLELEMENTNAME)){
JAXBElement<Test> unmarshalledObj = unmarshaller.unmarshal(reader, Test.class);
Test item = unmarshalledObj.getValue();
System.out.println(">" + item.getKey());
// The unmarshaller will have moved the pointer in the
// stream reader - we should now be pointing at the
// next event immediately after the unmarshalled
// element.
// This will either the start of the next element, or
// CHARACTERS if there is whitespace in between them,
// or something else like a comment.
// We need to check this to decide whether we can
// unmarshall again, or if we need to move the
// stream reader on to get to the next element.
readerEvent = reader.getEventType();
}
// move the stream reader on to the next element
readerEvent = reader.next();
}
// reached the end of the document - close the reader
reader.close();
}
catch (Exception exc){
exc.printStackTrace();
}
}
}
@XmlRootElement(name=Test.XMLELEMENTNAME)
public static class Test {
public static final String XMLELEMENTNAME = "test";
protected String key;
@XmlAttribute
public String getKey() {
return key;
}
public void setKey(String value) {
this.key = value;
}
}
}
@notsaltfish
Copy link

notsaltfish commented Aug 28, 2017

Hi,dalelane
I have changed your code to
if (readerEvent == XMLStreamConstants.START_ELEMENT && reader.getLocalName().equals(Test.XMLELEMENTNAME)){
JAXBElement unmarshalledObj = unmarshaller.unmarshal(reader, Test.class);
Test item = unmarshalledObj.getValue();
System.out.println(">" + item.getKey());
readerEvent = reader.getEventType();
}
else{
readerEvent = reader.next();
}
Just change the while loop to if-else block .And it also prints the same result as your original code was.I don't know is there any problem with my code,so if you find any bug in this code,please let me know .
Thanks,
Best regards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment