Depending on the actual structure of your XML and what you want to achieve.
Maybe using XPath could be an alternative way, if you need only few values from the XML input.
Find a small snippet below.
import java.io.ByteArrayInputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
...
String in = "<XmlParent>\n"
+ " <name>koraytugay</name>\n"
+ " <bar>\n"
+ " <baz>\n"
+ " <qux>00000001</qux>\n"
+ " </baz>\n"
+ " </bar>\n"
+ "</XmlParent>";
byte[] bytes = in.getBytes();
DocumentBuilder builder = DocumentBuilderFactory.newInstance()
.newDocumentBuilder();
Document document = builder.parse(new ByteArrayInputStream(bytes));
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
String name = xpath.evaluate("/XmlParent/name", document);
String qux = xpath.evaluate("/XmlParent/bar/baz/qux", document);
System.out.println("name = " + name);
System.out.println("qux = " + qux);
output
name = koraytugay
qux = 00000001
edit You could extend XMLEventReader
and check on each event if it is a XML tag you want to skip.
The XML event reader.
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
public class FilteringlXmlEventReader implements XMLEventReader {
final XMLEventReader reader;
final Set<QName> qNames;
public FilteringlXmlEventReader(XMLEventReader reader,
Set<QName> qNames) {
this.reader = reader;
this.qNames = qNames;
}
@Override
public XMLEvent nextEvent() throws XMLStreamException {
while (tagToSkip(reader.peek())) {
reader.nextEvent();
}
return reader.nextEvent();
}
// from XMLEventReader
@Override
public boolean hasNext() {
return reader.hasNext();
}
@Override
public XMLEvent peek() throws XMLStreamException {
return reader.peek();
}
@Override
public String getElementText() throws XMLStreamException {
return reader.getElementText();
}
@Override
public XMLEvent nextTag() throws XMLStreamException {
return reader.nextTag();
}
@Override
public Object getProperty(String name) throws IllegalArgumentException {
return reader.getProperty(name);
}
// from Iterator
@Override
public Object next() {
return reader.next();
}
@Override
public void remove() {
reader.remove();
}
@Override
public void close() throws XMLStreamException {
reader.close();
}
/**
* Check if the name of the XML tag which has triggered the passed
* event is to be skipped.
*
* @param event the current event
* @return {@code true} the event should be skipped, otherwise
* {@code false}
*/
private boolean tagToSkip(XMLEvent event) {
switch (event.getEventType()) {
case XMLStreamConstants.START_ELEMENT:
StartElement startTag = (StartElement) event;
return qNames.contains(startTag.getName());
case XMLStreamConstants.END_ELEMENT:
EndElement endTag = (EndElement) event;
return qNames.contains(endTag.getName());
}
return false;
}
}
The JAXB class.
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "XmlParent")
public class FooBar {
private String name;
private String qux;
@XmlElement
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlElement
public String getQux() {
return qux;
}
public void setQux(String qux) {
this.qux = qux;
}
}
A example app to show the principle.
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Set;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import sub.optimal.xpath.FooBar;
public class FilteredUnmarshalling {
public static void main(String[] args) throws Exception {
String in = "<XmlParent>\n"
+ " <name>koraytugay</name>\n"
+ " <bar>\n"
+ " <baz>\n"
+ " <qux>00000001</qux>\n"
+ " </baz>\n"
+ " </bar>\n"
+ "</XmlParent>";
byte[] bytes = in.getBytes();
JAXBContext context = JAXBContext.newInstance(FooBar.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
XMLInputFactory factory = XMLInputFactory.newInstance();
String[] tagNamesToFilter = {"bar", "baz"};
Set<QName> tagsToFilter = new HashSet<>();
for (String name : tagNamesToFilter) {
tagsToFilter.add(new QName(name));
}
try (InputStream reader = new ByteArrayInputStream(bytes)) {
XMLEventReader xmlEventReader=factory.createXMLEventReader(reader);
FooBar fooBar = (FooBar)unmarshaller.unmarshal(
new FilteringlXmlEventReader(xmlEventReader,tagsToFilter));
System.out.println("name: " + fooBar.getName());
System.out.println("qux : " + fooBar.getQux());
}
}
}
output
name: koraytugay
qux : 00000001