2

我希望针对 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方法(几乎可以肯定是一个错误),当我打印出类名时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)。

有没有人有类似的经历?

4

1 回答 1

2

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

-Djaxp.debug 会在您调用您正在调用的 JAXP APIS 时明确告诉您哪个实现处于活动状态。

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

编辑

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

于 2011-02-19T23:37:36.847 回答