簡體   English   中英

發現從元素“元素”開始的無效內容。 預期為“元素”之一

[英]Invalid content was found starting with element 'Element'. One of 'Element' is expected

我正在使用Java的JAXB解析器將XML文件編組和解編為特定的類。 取消編組工作正常,但是,在編組文件時出現以下錯誤而導致阻塞:

cvc-complex-type.2.4.a:發現無效的內容(從元素“ DataPath”開始)。 預期使用“ {” http://hg.flyingwhales.nl/cinnabar/schemas/project.xsd“:DataPath }”之一。

我不明白為什么這行不通,導致解​​組文件工作正常。

根據要求,這是一個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 by Jesse on 11/13/2016.
 */

public final class ProjectRepository {
    private static Validator validator;
    private static Marshaller marshaller;
    private static Unmarshaller unmarshaller;

    // This class is not meant to be 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;
    }
}

包信息.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 and parse a file from the filesystem.
        try {
            Project loadedProject = ProjectRepository.load(new File("Test.cinnabar"));
            System.out.print("Loaded project: " + loadedProject.getName());
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Try to create a project and save it to the 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>

朱砂

<?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>

只需運行代碼,它將產生錯誤。 確保project.xsd在工作目錄中。

您可以在`Project.java中添加propOrder

package nl.flyingwhales.hg.cinnabar.schemas.project;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "dataPath",
    "scriptPath",
    "artPath",
    "sfxPath",
    "bgmPath"
})
@XmlRootElement(name = "Project")
public class Project {

    @XmlElement(name = "DataPath", required = true)
    protected String dataPath;
    @XmlElement(name = "ScriptPath", required = true)
    protected String scriptPath;
    @XmlElement(name = "ArtPath", required = true)
    protected String artPath;
    @XmlElement(name = "SFXPath", required = true)
    protected String sfxPath;
    @XmlElement(name = "BGMPath", required = true)
    protected String bgmPath;
    @XmlAttribute(name = "name", required = true)
    protected String name;
    @XmlAttribute(name = "type", required = true)
    protected String type;

    //getter and setters
}

兩件事情:

  • 您的package-info.java缺少elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED
  • 正如@sahoora正確注意的那樣,在編組時,還需要propOrder來對元素進行正確排序。

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 { ... }

問題的核心是缺少elementFormDefault=QUALIFIED 這導致本地元素在空的命名空間中被編組,因此架構驗證和后續的解組失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM