java - Invalid content was found starting with element 'Element'. One of 'Element' is expected -
i'm using java's jaxb parser marshal , unmarshal xml files specific class. unmarshaling works fine, however, chokes on marshaling file following error:
cvc-complex-type.2.4.a: invalid content found starting element 'datapath'. 1 of '{"http://hg.flyingwhales.nl/cinnabar/schemas/project.xsd":datapath}' expected.
i don't understand why wouldn't work, cause unmarshaling file works fine.
as requested, here mcve:
projectrepository.java:
package com.flyingwhales; import org.xml.sax.saxexception; import javax.xml.xmlconstants; import javax.xml.bind.jaxbcontext; import javax.xml.bind.jaxbexception; import javax.xml.bind.marshaller; import javax.xml.bind.unmarshaller; import javax.xml.transform.source; import javax.xml.transform.stream.streamsource; import javax.xml.validation.schema; import javax.xml.validation.schemafactory; import javax.xml.validation.validator; import java.io.file; import java.io.ioexception; /** * created jesse on 11/13/2016. */ public final class projectrepository { private static validator validator; private static marshaller marshaller; private static unmarshaller unmarshaller; // class not meant instantiated. private projectrepository() {} static { file schemafile = new file("project.xsd"); schemafactory schemafactory = schemafactory .newinstance(xmlconstants.w3c_xml_schema_ns_uri); try { schema schema = schemafactory.newschema(schemafile); validator = schema.newvalidator(); // initialize jaxb stuff too. jaxbcontext jaxbcontext = jaxbcontext.newinstance(project.class); marshaller = jaxbcontext.createmarshaller(); marshaller.setproperty(marshaller.jaxb_formatted_output, true); marshaller.setschema(schema); unmarshaller = jaxbcontext.createunmarshaller(); } catch (saxexception | jaxbexception e) { e.printstacktrace(); } } public static project load(file file) throws exception { if (!validate(file)) { throw new exception("project file contains invalid markup"); } project project = (project)unmarshaller.unmarshal(file); project.setprojectfile(file); return project; } public static void save(project project, file path) throws jaxbexception { marshaller.marshal(project, path); } public static boolean validate(file file) throws ioexception { source source = new streamsource(file); try { validator.validate(source); } catch (saxexception e) { return false; } return true; } }
project.java
package com.flyingwhales; import javax.xml.bind.annotation.xmlattribute; import javax.xml.bind.annotation.xmlelement; import javax.xml.bind.annotation.xmlrootelement; import java.io.file; @xmlrootelement(name = "project") public class project { private string name = "project"; private string type = "standalone"; private string datapath = "data"; private string scriptpath = "data/scripts"; private string artpath = "art"; private string sfxpath = "sound/sfx"; private string bgmpath = "sound/bgm"; private file projectfile; public project() { } public project(file file) { setprojectfile(file); } @xmlattribute( name = "name" ) public string getname() { return name; } public void setname(string name) { this.name = name; } @xmlattribute (name = "type" ) public string gettype() { return type; } public void settype(string type) { this.type = type; } @xmlelement(name = "datapath") public string getdatapath() { return datapath; } public void setdatapath(string datapath) { this.datapath = datapath; } @xmlelement (name = "scriptpath") public string getscriptpath() { return scriptpath; } public void setscriptpath(string scriptpath) { this.scriptpath = scriptpath; } @xmlelement (name = "artpath") public string getartpath() { return artpath; } public void setartpath(string artpath) { this.artpath = artpath; } @xmlelement (name = "sfxpath") public string getsfxpath() { return sfxpath; } public void setsfxpath(string sfxpath) { this.sfxpath = sfxpath; } @xmlelement (name = "bgmpath") public string getbgmpath() { return bgmpath; } public void setbgmpath(string bgmpath) { this.bgmpath = bgmpath; } void setprojectfile(file file) { projectfile = file; } public file getprojectfile() { return projectfile; } }
package-info.java
@xmlschema(namespace = "http://hg.flyingwhales.nl/cinnabar/schemas/project.xsd") package com.flyingwhales; import javax.xml.bind.annotation.xmlschema;
main.java
package com.flyingwhales; import javax.xml.bind.jaxbexception; import java.io.file; public class main { public static void main(string[] args) { // open , parse file filesystem. try { project loadedproject = projectrepository.load(new file("test.cinnabar")); system.out.print("loaded project: " + loadedproject.getname()); } catch (exception e) { e.printstacktrace(); } // try create project , save hard drive. project newproject = new project(new file("new.cinnabar")); try { projectrepository.save(newproject, new file("new.cinnabar")); } catch (jaxbexception e) { e.printstacktrace(); } } }
project.xsd
<?xml version="1.0" encoding="utf-8" ?> <xs:schema xmlns:xs="http://www.w3.org/2001/xmlschema" targetnamespace="http://hg.flyingwhales.nl/cinnabar/schemas/project.xsd" xmlns="http://hg.flyingwhales.nl/cinnabar/schemas/project.xsd" elementformdefault="qualified"> <xs:element name="project"> <xs:complextype> <xs:sequence> <xs:element name="datapath" type="xs:string" /> <xs:element name="scriptpath" type="xs:string" /> <xs:element name="artpath" type="xs:string" /> <xs:element name="sfxpath" type="xs:string" /> <xs:element name="bgmpath" type="xs:string" /> </xs:sequence> <xs:attribute name="name" type="xs:string" use="required" /> <xs:attribute name="type" type="xs:string" use="required" /> </xs:complextype> </xs:element> </xs:schema>
test.cinnabar
<?xml version="1.0" encoding="utf-8"?> <project name="test project" type="standalone" xmlns="http://hg.flyingwhales.nl/cinnabar/schemas/project.xsd" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://hg.flyingwhales.nl/cinnabar/schemas/project.xsd"> <datapath>data</datapath> <scriptpath>data/scripts</scriptpath> <artpath>art</artpath> <sfxpath>sound/sfx</sfxpath> <bgmpath>sound/bgm</bgmpath> </project>
simply run code , produce error. make sure project.xsd in working directory.
two things:
- your package-info.java missing
elementformdefault = javax.xml.bind.annotation.xmlnsform.qualified
- as @sahoora correctly noticed, need
proporder
correct ordering of elements when marshalling.
package-info.java
:
@xmlschema(namespace = "http://hg.flyingwhales.nl/cinnabar/schemas/project.xsd", elementformdefault = javax.xml.bind.annotation.xmlnsform.qualified) package com.flyingwhales; import javax.xml.bind.annotation.xmlschema;
project.java
:
@xmlrootelement(name = "project") @xmltype(name = "", proporder = { "datapath", "scriptpath", "artpath", "sfxpath", "bgmpath" }) public class project { ... }
the core of problem missing elementformdefault=qualified
. lead local elements marshalled in empty namespace therefore schema validation , subsequent unmarshalling failed.
Comments
Post a Comment