Java XML验证:如何针对XSD验证XML文档
#java #xml #xsd

介绍我们的Java XML验证项目!掌握在Java环境中毫不费力地针对XSD验证XML的艺术。获得动手实践经验,确保数据的完整性和合规性。

1.简介

介绍我们的Java XML验证项目!在轻松验证XML文档时获得动手实践经验。该项目是实用指南,为您提供必要的知识和工具,以确保您在Java环境中XML数据的完整性和合规性。发现我们的分步方法的简单性,该方法可以使您完成整个验证过程。掌握毫不费力地验证XML并在数据上释放新的信心的艺术。加入我们的旅程,因为我们使您能够利用Java项目中XML验证的力量。

2.从XSD生成Java类

对于此练习,我们将使用来自w3schools https://www.w3schools.com/xml/schema_example.asp的XSD。

要能够从XSD生成Java类,我们将使用Eclipse Enterprise Edition。 Intellij也可以使用Jakarta插件来完成,但是Eclipse的性能更好,尤其是在处理XJB文件时。

Intellij

Image description

eclipse jaxb类生成器

Image description

生成的类

Image description

3.依赖关系

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

<dependency>
    <groupId>jakarta.activation</groupId>
    <artifactId>jakarta.activation-api</artifactId>
    <version>2.1.1</version>
</dependency>
<dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
    <version>${jakarta.version}</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>${jakarta.version}</version>
    <scope>runtime</scope>
</dependency>

4.核心类

运行验证并抛出违反约束的标签的适当异常或名称,我们需要以下类。

4.1 Resourceresolver

例如,如果我们将使用XML数字签名,则导入外部XSD。

<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd"/>

public class ResourceResolver implements LSResourceResolver {

  private static final Logger LOGGER = LoggerFactory.getLogger(ResourceResolver.class);

  public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {

    // note: in this sample, the XSD's are expected to be in the root of the classpath
    InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("xsd/" + systemId);
    return new Input(publicId, systemId, resourceAsStream);
  }

  static class Input implements LSInput {

    private String publicId;

    private String systemId;

    public String getStringData() {

      String textDataFromFile;

      try {
        BufferedReader bufferReader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder stringBuilder = new StringBuilder();
        String eachStringLine;

        while ((eachStringLine = bufferReader.readLine()) != null) {
          stringBuilder.append(eachStringLine).append("\n");
        }
        textDataFromFile = stringBuilder.toString();

        return textDataFromFile;

      } catch (IOException e) {
        LOGGER.error("Fail reading from inputStream={}", e.getMessage());
        return null;
      }
    }
...

4.2 saxerrorhandler

让我们能够知道抛出约束异常的标签,我们需要定义一个自定义异常,该异常接受XMLStreamReader对象,我们可以在其中获取LocalName属性。

public class SaxErrorHandler implements ErrorHandler {

  private XMLStreamReader reader;

  public SaxErrorHandler(XMLStreamReader reader) {
    this.reader = reader;
  }

  @Override
  public void error(SAXParseException e) {
    warning(e);
  }

  @Override
  public void fatalError(SAXParseException e) {
    warning(e);
  }

  @Override
  public void warning(SAXParseException e) {

    throw new XmlValidationException(reader.getLocalName());
  }
}

4.3其他课程

我们还需要以下公用事业课程:

  • 创建一个jaxbelement
  • 将jaxbelement转换为XMLStreamReader
  • 定义正确的编组对象

这些课程都可以在项目中提供。

4.4 XMLSchemavalidator接口

最后,将所有组件拼凑在一起进行验证的接口。

default void validateXMLSchema(String xsdPath, JAXBElement<?> xml) {

  Validator validator = null;
  try {
    SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
    factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
    factory.setResourceResolver(new ResourceResolver());

    Schema schema = factory.newSchema(ResourceUtils.getFile(xsdPath));
    validator = schema.newValidator();
    XMLStreamReader xmlStreamReader = asStreamReader(xml);

    ErrorHandler errorHandler = new SaxErrorHandler(xmlStreamReader);
    validator.setErrorHandler(errorHandler);

    validator.validate(new StAXSource(xmlStreamReader));

  } catch (IOException | SAXException | JAXBException | XMLStreamException e) {

    var xmlEx = getXmlValidationExceptionIfPresent(e);
    throw new InvalidXmlException(xmlEx.getLocalName(), e);
  }
}

5.源代码 / git存储库

此项目的完整源代码可在https://github.com/czetsuyatech/java-xml-validation-by-xsd的我的赞助商中使用。

赞助链接:https://github.com/sponsors/czetsuya

项目屏幕截图

Image description