如何在Java中针对XSD验证XML?

该javax.xml.validation软件包提供了用于XML文档验证的API。验证过程将验证XML文档是指定的XML模式文件或XSD文件的实例。在此示例中,我们将验证records.xml下面的文件是否在records.xsd架构实例中。首先,我们将创建以下XML文件和应遵循的XSD文件。

XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <records>
        <record>
            <title>Brand New Eyes</title>
            <artist>Paramore</artist>
            <genre>Punk Rock</genre>
            <year>2011</year>
        </record>
        <record>
            <artist>Various Artist</artist>
            <genre>Rock</genre>
            <year/>
        </record>
    </records>
</root>

XSD文件:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified"
           elementFormDefault="qualified">
    <xs:element name="root" type="rootType">
    </xs:element>

    <xs:complexType name="rootType">
        <xs:sequence>
            <xs:element name="records" type="recordsType"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="recordsType">
        <xs:sequence>
            <xs:element name="record" type="recordType" maxOccurs="unbounded" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="recordType">
        <xs:sequence>
            <xs:element type="xs:string" name="title"/>
            <xs:element type="xs:string" name="artist"/>
            <xs:element type="xs:string" name="genre"/>
            <xs:element type="xs:short" name="year"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

下面的代码段将在以下步骤中处理验证过程。在main()方法中,我们创建XMLValidator实例并调用该validate()方法,并传递XML文件和XSD文件。我们的validate()方法首先创建的实例SchemaFactory。该SchemaFactory.newInstance()方法返回的实例SchemaFactory。在此示例中,我们将创建一个W3C XML模式。

下一步是Schema通过调用schemaFactory.newSchema()并创建一个对象,然后传递模式/ XSD文件。该Schema对象将允许我们javax.xml.validation.Validator通过调用schema.newValidator()方法来创建的实例。最后,为了验证XML是否有效,我们调用validator.validate()方法并传递要验证的XML文件。如果XML无效,则此validate方法将引发异常。

Java代码:

package org.nhooo.example.xml;

import org.xml.sax.SAXException;

import javax.xml.XMLConstants;
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.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.Objects;

public class XMLValidator {
    public static final String XML_FILE = "records.xml";
    public static final String SCHEMA_FILE = "records.xsd";

    public static void main(String[] args) {
        XMLValidator XMLValidator = new XMLValidator();
        boolean valid = XMLValidator.validate(XML_FILE, SCHEMA_FILE);

        System.out.printf("%s validation = %b.", XML_FILE, valid);
    }

    private boolean validate(String xmlFile, String schemaFile) {
        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        try {
            Schema schema = schemaFactory.newSchema(new File(getResource(schemaFile)));

            Validator validator = schema.newValidator();
            validator.validate(new StreamSource(new File(getResource(xmlFile))));
            return true;
        } catch (SAXException | IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    private String getResource(String filename) throws FileNotFoundException {
        URL resource = getClass().getClassLoader().getResource(filename);
        Objects.requireNonNull(resource);

        return resource.getFile();
    }
}