【问题标题】:Validating XML files in Java against two schemas with same namespace针对具有相同命名空间的两个模式验证 Java 中的 XML 文件
【发布时间】:2011-02-24 12:28:42
【问题描述】:

我有

  1. 一个 XML 文档,
  2. 基本 XSD 文件和
  3. 扩展的 XSD 文件。

两个 XSD 文件都有一个命名空间。

文件 3) 包括文件 2):<xs:include schemaLocation="someschema.xsd"></xs:include>

XML 文档(文件 1)具有以下根标记:

<tagDefinedInSchema xmlns="http://myurl.com/myapp/myschema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://myurl.com/myapp/myschema schemaFile2.xsd">

schemaFile2.xsd 是上面的文件 3。

我需要针对两种模式验证文件 1,而不需要

  1. 修改文件本身和

  2. 将两个模式合并到一个文件中。

如何在 Java 中做到这一点?

UPD:这是我正在使用的代码。

SchemaFactory schemaFactory = SchemaFactory
        .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
DocumentBuilderFactory documentFactory = DocumentBuilderFactory
        .newInstance();
documentFactory.setNamespaceAware(namespaceAware);
DocumentBuilder builder = documentFactory.newDocumentBuilder();
Document document = builder.parse(new ByteArrayInputStream(xmlData
        .getBytes("UTF-8")));

File schemaLocation = new File(schemaFileName);
Schema schema = schemaFactory.newSchema(schemaLocation);

Validator validator = schema.newValidator();

Source source = new DOMSource(document);

validator.validate(source);

UPD 2:这对我有用:

    public static void validate(final String xmlData,
        final String schemaFileName, final boolean namespaceAware)
        throws SAXException, IOException {
    final SchemaFactory schemaFactory = SchemaFactory
            .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    schemaFactory.setResourceResolver(new MySchemaResolver());
    final Schema schema = schemaFactory.newSchema();

    final Validator validator = schema.newValidator();
    validator.setResourceResolver(schemaFactory.getResourceResolver());

    final InputSource is = new InputSource(new ByteArrayInputStream(xmlData
            .getBytes("UTF-8")));
    validator.validate(new SAXSource(is), new SAXResult(new XMLReaderAdapter()));
}



class MySchemaResolver implements LSResourceResolver {

@Override
public LSInput resolveResource(final String type,
        final String namespaceURI, final String publicId, String systemId,
        final String baseURI) {
    final LSInput input = new DOMInputImpl();
    try {
        if (systemId == null) {
            systemId = SCHEMA1;
        }
        FileInputStream fis = new FileInputStream(
                new File("path_to_schema_directory/" + systemId));

        input.setByteStream(fis);
        return input;
    } catch (FileNotFoundException ex) {
        LOGGER.error("File Not found", ex);
        return null;
    }

}

}

【问题讨论】:

  • 你使用什么机制来解析文件?
  • 我将代码添加到我的问题中。
  • 在你的代码中 schemaFileName 应该是 schemaFile2.xsd (扩展的 XSD 文件),这是你在做什么?
  • 我试过了,但是当我这样做时,我得到一个错误 - 未找到架构 1 中定义的标签。我修改了上面显示的代码(UPD 2),现在它可以工作了。
  • 第二次更新中的 SCHEMA1 是什么?

标签: java xml xsd


【解决方案1】:

一些术语:这里有一个架构,它是由两个架构文档构建的。

如果您在构建 Schema 时向 API 指定 schemaFile2.xsd,它应该通过 xs:include 自动拉入另一个文档。如果您怀疑这没有发生,您需要解释是什么症状导致您相信这一点。

【讨论】:

  • 它不会拉取包含的文档。症状:我收到一条错误消息,例如“未找到元素 X 的定义”,并且该元素是在包含的 XSD 中定义的。我已经解决了我的问题(见上文,UPD 2)。
【解决方案2】:

这可能看起来有点低效,但您不能针对架构 A 进行验证,使用架构 B 创建一个新的验证器并针对该验证器进行验证吗?

【讨论】:

  • 这不起作用,因为第二个架构包含第一个架构。当我针对第二个架构验证代码时,找不到包含的架构的元素。
  • 那么问题是你不确定如何从schema2引用schema1?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-13
  • 2012-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-12
  • 1970-01-01
相关资源
最近更新 更多