GETTING THE FRAGMENT
The way that you are currently getting the XML fragment is causing the namespace declarations to be lost. In your fragment ns2
is no longer a prefix, you just have a element name with a colon in it (ns2:Person
). This is going to cause problems with namespace aware parsers. The article below may be a better approach for you to get the XML fragment:
HANDLING YOUR USE CASE
Using the XML fragment that you have, you could create an XMLFilter
that removes the prefix from the XML element, and then leverage JAXB's UnmarshallerHandler
to do the unmarshalling.
Demo
package forum11968399;
import java.io.StringReader;
import javax.xml.bind.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.XMLFilterImpl;
public class Demo {
private static final String xml = "<ns2:Person name='John' age='20' />";
public static void main(String[] args) throws Exception {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xmlReader = sp.getXMLReader();
XMLFilter xmlFilter = new MyXMLFilter(xmlReader);
JAXBContext context = JAXBContext.newInstance(PersonEntity.class);
Unmarshaller um = context.createUnmarshaller();
UnmarshallerHandler unmarshallerHandler = um.getUnmarshallerHandler();
xmlFilter.setContentHandler(unmarshallerHandler);
StringReader sr = new StringReader(xml);
xmlFilter.parse(new InputSource(sr));
PersonEntity p = (PersonEntity) unmarshallerHandler.getResult();
}
private static class MyXMLFilter extends XMLFilterImpl {
public MyXMLFilter(XMLReader xmlReader) {
super(xmlReader);
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
int colonIndex = qName.indexOf(':');
if(colonIndex >= 0) {
qName = qName.substring(colonIndex + 1);
}
uri = XML_NAMESPACE; //to prevent unknown XML element exception, we have to specify the namespace here
super.startElement(uri, localName, qName, attributes);
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
int colonIndex = qName.indexOf(':');
if(colonIndex >= 0) {
qName = qName.substring(colonIndex + 1);
}
super.endElement(uri, localName, qName);
}
}
}
PersonEntity
package forum11968399;
import javax.xml.bind.annotation.*;
@XmlRootElement(name="Person")
@XmlAccessorType(XmlAccessType.FIELD)
public class PersonEntity {
@XmlAttribute
private String name;
@XmlAttribute
private int age;
}