【问题标题】:Xerces XMLSchemaFactory: Cannot find the declaration of elementXerces XMLSchemaFactory:找不到元素的声明
【发布时间】:2011-02-19 17:58:44
【问题描述】:

我希望根据 XSD 文件验证 XML 文件(在 XML 文件中没有命名空间,也没有架构声明)。

XML 文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<report> ... </report>

XSD 文件是:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="report">
    ...
  </xs:element>
</xs:schema>

代码类似如下:

SchemaFactory xsdFac = SchemaFactory.newInstance(
   XMLConstants.W3C_XML_SCHEMA_NS_URI);
xsdFac.setErrorHandler( ... );
Schema xsd = xsdFac.newSchema(xsdUrl);  // xsdUrl works
Validator xsdValidator = xsd.newValidator();
xsdValidator.validate(new DOMSource(doc));  // doc is correct

我在这上面花了 3 个小时,因为它在我的 PC 上本地工作,它曾经在服务器上工作(我认为),但现在它不能在服务器上工作。我试图找出我的 PC 和服务器之间的差异,但它们都使用相同的 JAR,等等。

无论如何,我已经确定了以下差异。我没有将类名传递给SchemaFactory.newInstance 方法(几乎可以肯定是mistake),当我打印出xsdFac 的类名时,我发现它在本地和服务器上有所不同。我不认为我想了解为什么会这样(我不知道),我认为最好找到一个有效的,并明确指定它。

  • 在我的电脑上(工作)是com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory。如果我在 newInstance 调用中明确指定,那么它可以在 PC 和服务器上运行。
  • 在服务器上(不起作用),它是org.apache.xerces.jaxp.validation.XMLSchemaFactory。如果我在 newInstance 调用中明确设置,那么我在 PC 和服务器上都会收到相同的错误。

注意com.sun 在有效的开头。

所以至少我有一个解决方案,这很好。但是,我认为我不应该在我的代码中明确使用 com.sun 类?

其他信息:

  • 我得到的错误是:org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'report'
  • 这与我在工作版本上将元素名称更改为其他名称(架构中不存在的名称)时遇到的错误相同。所以我认为这只是意味着,“我了解您的架构,我了解 XML,并且您使用了一个未在架构中任何地方声明的元素。”
  • xercesImpl-2.9.1.jar 在我的项目中(在服务器上和 PC 上)。
  • 这个 JAR 在非工作版本上指定的包下包含一个 XMLSchemaFactory.class(即让我相信它在那里、可找到并且应该工作,毕竟我没有得到任何与类相关的异常找到)
  • 我正在解析的doc 对象在这两种情况下都是org.apache.xerces.dom.DeferredDocumentImpl

所以,我的问题是:我想使用模式工厂的显式 Xerces 实现(我认为),因为我包含 JAR 并且我有一个来自 Xerces 的 Document 对象,基本上我无论如何都在使用 Xerces 验证器(在com.sun的工作案例中)。

有人有类似经历吗?

【问题讨论】:

    标签: java xerces xml-validation


    【解决方案1】:

    我会冒险猜测,在失败的情况下,您实际上在类路径上没有 Xerces。

    -Djaxp.debug 会在您调用您正在调用的 JAXP APIS 时确定哪个实现是活动的。

    如果是这样,而且这不仅仅是类路径中错误的结果,您确实可以专门“新建”Xerces 类,而不是调用 JAXP 通用工厂方法。我已经做到了。

    编辑

    cmets 表示这是一个 webapp。考虑到类加载规则,JAXP 类是在 web 应用程序中放入痛苦的东西之一。您至少应该尝试将它放在 tomcat 的“系统”类路径中,看看会发生什么。

    【讨论】:

    • 好的,谢谢,我会试一试并回复您!但是系统(在失败的情况下)确实实例化了org.apache.xerces.jaxp.validation.XMLSchemaFactory(我通过System.out.println(fac.getClass())得到了那个类名,所以我认为它一定在类路径上?
    • 是的,这听起来很有希望。但是您可能以某种方式设法获得了 Xerces 和非 Xerces 的奇怪混合物。等等,我看错了。
    • 是的,我确实觉得“奇怪的混合物”正是正在发生的事情,尽管我无法证明这一点。我的意思是说文档不符合架构(但没有其他错误,例如找不到类),当 XML 和 XSD 文件可用时,另一个实现说一切正常,....嗯。
    • 或者可能是类加载问题?我是否需要“认可”Tomcat 等中的 Xerces JAR,否则与 SchemaFactory.newInstance(系统类)关联的类加载器无法找到我的 Xerces JAR(在我的 WAR 中)?
    • 哦,一个 WAR 文件。你去吧。最简单的是将 Xerces 放在 tomcat 的系统类加载器中,而不是放在 webapp 中。
    猜你喜欢
    • 1970-01-01
    • 2012-07-02
    • 2012-11-28
    • 2012-09-14
    • 2016-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多