フラグメントの取得
現在XMLフラグメントを取得している方法により、名前空間宣言が失われています。フラグメントns2
にはプレフィックスがなくなり、コロンが含まれる要素名が含まれるだけです(ns2:Person
)。これにより、名前空間対応のパーサーで問題が発生します。以下の記事は、XMLフラグメントを取得するためのより良いアプローチかもしれません。
ユースケースの処理
持っているXMLフラグメントを使用してXMLFilter
、XML要素からプレフィックスを削除するを作成し、JAXBを利用UnmarshallerHandler
してアンマーシャリングを行うことができます。
デモ
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;
}