java - How to unmarshall xml with different namespaces -
i use jaxb 2.0 , want unmarshall xml getting validation errors. example if element or attribute missed. here xml want parse:
<?xml version="1.1" encoding="utf-8"?> <package version="2.0" xmlns="http://www.idpf.org/2007/opf"> <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf"> <dc:title>title</dc:title> </metadata> </package>
my model classes:
@xmlaccessortype(xmlaccesstype.field) @xmlrootelement(name = "package") public class package { @xmlelement(required = true) public metadata metadata; @xmlattribute(name = "version", required = true) public string version; } @xmlaccessortype(xmlaccesstype.field) @xmlrootelement(name = "metadata") public class metadata { @xmlelement(namespace = "http://purl.org/dc/elements/1.1/", required = true) public string title; }
package-info.java has annotation:
@javax.xml.bind.annotation.xmlschema(namespace = "http://www.idpf.org/2007/opf", elementformdefault = javax.xml.bind.annotation.xmlnsform.qualified)
and code unmarshalling:
jaxbcontext jc = jaxbcontext.newinstance(package.class); unmarshaller unmarshaller = jc.createunmarshaller(); final list<bytearrayoutputstream> outs = new arraylist<>(); jc.generateschema(new schemaoutputresolver(){ @override public result createoutput(string namespaceuri, string suggestedfilename) throws ioexception { bytearrayoutputstream out = new bytearrayoutputstream(); outs.add(out); streamresult streamresult = new streamresult(out); streamresult.setsystemid(""); return streamresult; }}); streamsource[] sources = new streamsource[outs.size()]; (int i=0; i<outs.size(); i++) { bytearrayoutputstream out = outs.get(i); system.out.append(new string(out.tobytearray())); sources[i] = new streamsource(new bytearrayinputstream(out.tobytearray()),""); } schemafactory sf = schemafactory.newinstance(xmlconstants.w3c_xml_schema_ns_uri); schema schema = sf.newschema(sources); unmarshaller.setschema(schema); unmarshaller.seteventhandler(event -> { system.out.append(event.tostring()); return true; }); opf file = (opf) unmarshaller.unmarshal(opffile);
it generates schema:
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <xs:schema elementformdefault="qualified" version="1.0" targetnamespace="http://www.idpf.org/2007/opf" xmlns:tns="http://www.idpf.org/2007/opf" xmlns:xs="http://www.w3.org/2001/xmlschema" xmlns:ns1="http://purl.org/dc/elements/1.1/"> <xs:import namespace="http://purl.org/dc/elements/1.1/"/> <xs:element name="metadata" type="tns:metadata"/> <xs:element name="package" type="tns:package"/> <xs:complextype name="package"> <xs:sequence> <xs:element ref="tns:metadata"/> </xs:sequence> <xs:attribute name="version" type="xs:anysimpletype" use="required"/> </xs:complextype> <xs:complextype name="metadata"> <xs:sequence> <xs:element ref="ns1:title"/> </xs:sequence> </xs:complextype> </xs:schema> <?xml version="1.0" encoding="utf-8" standalone="yes"?> <xs:schema version="1.0" targetnamespace="http://purl.org/dc/elements/1.1/" xmlns:xs="http://www.w3.org/2001/xmlschema"> <xs:element name="title" type="xs:string"/> </xs:schema>
and during unmarshalling throw error: org.xml.sax.saxparseexception: src-resolve: cannot resolve name 'ns1:title' a(n) 'element declaration' component.
how should annotate classes parse xml file?
you have hands dirty resource resolver; below working code:
jaxbcontext jc = jaxbcontext.newinstance(package.class); unmarshaller unmarshaller = jc.createunmarshaller(); final map<string, bytearrayoutputstream> outs = new hashmap<string, bytearrayoutputstream>(); jc.generateschema(new schemaoutputresolver(){ @override public result createoutput(string namespaceuri, string suggestedfilename) throws ioexception{ bytearrayoutputstream out = new bytearrayoutputstream(); outs.put(suggestedfilename, out); streamresult streamresult = new streamresult(out); streamresult.setsystemid(suggestedfilename); return streamresult; }}); streamsource[] sources = new streamsource[outs.size()]; int = 0; (map.entry<string, bytearrayoutputstream> entry: outs.entryset()) { system.out.append(new string(entry.getvalue().tobytearray())); sources[i++] = new streamsource(new bytearrayinputstream(entry.getvalue().tobytearray()), entry.getkey()); } schemafactory sf = schemafactory.newinstance(xmlconstants.w3c_xml_schema_ns_uri); sf.setresourceresolver(new lsresourceresolver(){ @override public lsinput resolveresource(string type, string namespaceuri, string publicid, string systemid, string baseuri){ bytearrayoutputstream bout = outs.get(systemid); if(bout!=null){ return new dominputimpl(publicid, systemid, baseuri, new bytearrayinputstream(bout.tobytearray()), null); }else return null; } }); schema schema = sf.newschema(sources); unmarshaller.setschema(schema); unmarshaller.seteventhandler(new validationeventhandler(){ @override public boolean handleevent(validationevent event){ system.out.append(event.tostring()); return true; } }); object obj = unmarshaller.unmarshal(new file("package.xml"));
Comments
Post a Comment