在 Java 1.8 中针对 XSD v1.1 模式验证 xml 文件的示例


  • 我当前的验证不适用于XSD v1.1架构..我尝试了很多方法来改变这一点,但直到现在都没有成功
  • 使用Saxon或Xerces完成解决方案对我来说并不重要(编辑:我不想花钱解决问题,看起来Saxon XSD1.1验证不是免费的,所以我质疑我必须坚持使用Xerces)
  • 是的,我已经搜索了SO,但到目前为止,没有任何代码片段帮助我获得工作验证。
  • 代码是用于 eclipse-plugin 的,如果这应该重要的话
  • 我将以下jar文件添加到项目/类路径中,但是看起来它没有在我的代码中使用:
<dependency>
  <groupId>xerces</groupId>
  <artifactId>xercesImpl</artifactId>
  <version>2.11.0</version>
</dependency>

这里是我到目前为止用于验证的代码(如果它不能用于 xsd1.1,转储它没有问题):

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;
import org.apache.xerces.parsers.DOMParser;
import org.apache.xerces.xni.parser.XMLInputSource;
....
public List<MyError> validate(File xmlFile) {
    List<MyError> errors = null;
    try {
        DOMParser parser = new DOMParser();
        parser.setFeature(XmlUtils.VALIDATION, true);
        parser.setFeature(XmlUtils.VALIDATION_SCHEMA, true);
        parser.setFeature(XmlUtils.ALL_SCHEMA_LOCATIONS, true);
        parser.setFeature(XmlUtils.DEFER_NODE_EXPANSION, false);
        Handler handler = new Handler(xmlFile, parser);
        parser.setErrorHandler(handler);
        // there probably are smarter ways to do this
        String uri = xmlFile.toURI().toString().replace("%20", " ");
        InputStream inputStream = new FileInputStream(xmlFile);
        XMLInputSource inputSource = new XMLInputSource("", uri, uri, inputStream, "UTF-8");
        parser.parse(inputSource);
        errors = handler.getErrors();
    }
    catch (Exception e)
    {
        ConsoleHandler.printError("Document " + xmlFile.getName() + " has not been parsed correctly: " + e.getMessage(), true);
        ConsoleHandler.printStackTrace(e);
    }
    // printing the errors happens in some other method
    return errors;
}

您已经标记了这个"撒克逊人",所以我假设您正在寻找撒克逊人的解决方案。(但你也把它标记为"Xerces")。您已经显式实例化了 Xerces DOMParser,因此这里没有任何内容可以调用 Saxon 作为模式验证器。如果您想要Xerces解决方案,那么我不是专家,无法为您提供帮助。如果你想要一个撒克逊解决方案,你可以在撒克逊资源下载文件中找到很多例子(在SourceForge和 saxonica.com 上都有)。以下是一些摘录,大致可以满足您的需求:

S9API 示例:

            Processor proc = new Processor(true);
            SchemaManager sm = proc.getSchemaManager();
            sm.load(new StreamSource(new File("data/books.xsd")));
            try {
                SchemaValidator sv = sm.newSchemaValidator();
                sv.validate(new StreamSource(new File("data/books.xml")));
                System.out.println("First schema validation succeeded (as planned)");
            } catch (SaxonApiException err) {
                System.out.println("First schema validation failed");
            }

JAXP示例:

            System.setProperty("javax.xml.transform.TransformerFactory",
                               "com.saxonica.config.EnterpriseTransformerFactory");
            TransformerFactory factory = TransformerFactory.newInstance();
            System.err.println("TransformerFactory class: " + factory.getClass().getName());
            factory.setAttribute(FeatureKeys.SCHEMA_VALIDATION, new Integer(Validation.STRICT));
            factory.setAttribute(FeatureKeys.VALIDATION_WARNINGS, Boolean.TRUE);
            if (args.length > 1) {
                StreamSource schema = new StreamSource(new File(args[1]).toURI().toString());
                ((EnterpriseTransformerFactory)factory).addSchema(schema);
            }
            Transformer trans = factory.newTransformer();
            StreamSource source = new StreamSource(new File(args[0]).toURI().toString());
            SAXResult sink = new SAXResult(new DefaultHandler());
            trans.transform(source, sink);

好的,我终于让我的 XML 使用 Xerces 针对 XSD1.1 模式进行验证。这里我使用的依赖项:

<dependency>
    <groupId>org.opengis.cite.xerces</groupId>
    <artifactId>xercesImpl-xsd11</artifactId>
    <version>2.12-beta-r1667115</version>
</dependency>

(似乎还没有官方的xerces版本支持xsd1.1。首先让我感到困惑的是:Xercex v2.11.0 似乎不支持 XSD1.1,而 2.11.0.beta 支持 )

这是我使用的源代码:

import java.io.File;
import java.io.IOException;
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 org.xml.sax.SAXException;
public class MyClass {
    public static void main(String[] args) {
        try {
            validateFile(new File("Test.xml") , new  File("Test.xsd"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static void validateFile(File xmlFile, File xsdFile) throws SAXException, IOException
    {
        SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1");
        File schemaLocation = xsdFile;
        Schema schema = factory.newSchema(schemaLocation);
        Validator validator = schema.newValidator();
        Source source = new StreamSource(xmlFile);
        try
        {
            validator.validate(source);
            System.out.println(xmlFile.getName() + " is valid.");
        }
        catch (SAXException ex)
        {
            System.out.println(xmlFile.getName() + " is not valid because ");
            System.out.println(ex.getMessage());
        }
    }
}

编辑:但是我的代码尚未作为 eclipse-plugin 运行。在插件中触发验证时,我收到以下错误:

!ENTRY org.eclipse.core.jobs 4 2 2016-03-15 15:14:37.852
!MESSAGE An internal error occurred during: "validation job".
!STACK 0
javax.xml.validation.SchemaFactoryConfigurationError: Provider for class javax.xml.validation.SchemaFactory cannot be created
    at javax.xml.validation.SchemaFactoryFinder.findServiceProvider(SchemaFactoryFinder.java:414)
    at javax.xml.validation.SchemaFactoryFinder._newFactory(SchemaFactoryFinder.java:218)
    at javax.xml.validation.SchemaFactoryFinder.newFactory(SchemaFactoryFinder.java:145)
    at javax.xml.validation.SchemaFactory.newInstance(SchemaFactory.java:213)
    at plugin.control.validation.MyValidator.validateFile(MyValidator.java:39)
    at
...

引发异常的代码行:

SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1");

最新更新