【问题标题】:Parsing Schema in Java With imports and includes?使用导入和包含在 Java 中解析模式?
【发布时间】:2010-12-16 11:20:29
【问题描述】:

我正在尝试将一个相当复杂的 XML 模式解析加载到 Java 中的 Schema 对象中,这样我就可以对 XML 消息进行一些验证。

我的代码如下所示:

SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new StreamSource(new File("schema/schema.xsd")));

我的架构有很多导入:

<?xml version="1.0" encoding="UTF-8"?>
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="base_1">
  <xs:import namespace="base_1" schemaLocation="common/MessageBase.xsd"/>
</xs:schema>

...等等。当我尝试加载架构时,出现很多错误。基于与此相关的另一个问题,我似乎需要指定一个资源解析器,但这不是应该默认处理的事情吗?

如果是这样,我是否需要将架构放置在相对于我正在编写的应用程序运行位置或相对于基本架构文件的特定目录中?

最后,当我使用 XMLSpy 或类似工具加载架构时,它工作正常,我可以毫无问题地验证 XML 实例。

【问题讨论】:

    标签: java validation xsd jaxp


    【解决方案1】:

    如果您使用 URL 而不是 StreamSource,则不需要资源解析器。

    URL schemaURL = Thread.currentThread().getContextClassLoader().getResource(schemaFileName);
    SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    Schema schema = schemaFactory.newSchema(schemaURL);
    

    【讨论】:

    • 我已经使用 URL 完成了它,但是当它必须处理导入时仍然没有为我正确解析资源。我使用了 ResourceResolver,但它已修复。为什么它对你有用,而不是对我有用,这仍然是个问题。也许它与项目结构有关。我的 xsd 文件中的路径是相对于我的 java 类路径的,我最好的猜测是,你的路径可能是相对于你的工作文件夹。
    【解决方案2】:

    我认为 StreamSource 的使用,没有指定基本位置,是你问题的根源。

    解析器无法知道主架构在哪里,因此无法解析 common/MessageBase.xml。

    使用两个参数的构造函数并传入一个 SystemID,它是您开始的路径名。

    查看 StreamSource 的 javadoc。

    【讨论】:

    • 试过这个,仍然得到以下错误:src-resolve:无法将名称'base:StatusWithError_optional'解析为(n)'属性组'组件。
    • 这是一个不同的问题。这表明您的架构不完整且不独立。您是否有一个名为 StatusWithError_optional 的属性组?它在正确的命名空间中吗?
    • 是的,它在与基本模式文件相同级别的单独文件中定义。相同的命名空间。 systemID 应该是根 .xsd 文件的路径还是模式的根目录的路径? 2-arg 构造函数的另一个参数怎么样?
    • 系统 ID 应该是整个架构的路径。同样,您收到的错误表明查找导入的架构正在工作,但现在架构的内容存在实际问题。毕竟,第一个参数只是流或阅读器。
    • @bmargulies:花了 4 小时发现这就是为什么我的 xml 模式中的包含标签无法解析的原因后,我很乐意给你 +10 的答案 :) 另外到您的信息:实际上 StreamSource(File) 构造函数确实通过从 File 查询 URL 来设置 systemId 本身。这里的问题似乎是他通过了相对路径。我遇到了同样的问题,因为我使用了 StreamSource(InputStream),它当然也不提供有关路径的任何信息——除非你明确地设置它。供自己和他人将来参考:D
    【解决方案3】:

    为了解析导入的 XSD,您必须将架构工厂与资源解析器相关联:

    SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    factory.setResourceResolver(new MyResourceResolver());
    Schema schema = factory.newSchema(new StreamSource(new File("schema/schema.xsd")));
    

    有关更多详细信息,您可以查看此answer

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-18
      • 1970-01-01
      • 2012-01-14
      • 1970-01-01
      • 2017-05-31
      • 1970-01-01
      • 1970-01-01
      • 2020-11-23
      相关资源
      最近更新 更多