Java中的XML验证:processContents =“lax”似乎无法正常工作

时间:2011-10-19 11:42:44

标签: java xml xsd sax

我有一个包含许多

的XML Schema
<any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />

定义,即它允许插入其他命名空间的任意标记。 processContents="lax"表示解析器应尝试验证这些标记,如果它具有相应的模式(1) (2)

对我来说,这意味着,如果我向解析器提供所有模式文档,并且其中一个辅助名称空间的XML标记无效,则需要报告错误。

但是,似乎Java XML验证程序忽略了这些错误。我已经验证了解析器具有执行验证所需的所有模式文档(如果我将XML模式更改为processContents="strict",它将按预期工作并使用辅助模式文档进行验证)。似乎验证器的行为就像使用值skip指定属性一样。

验证的Java代码:

/*
 * xmlDokument is the file name of the XML document
 * xsdSchema is an array with all schema documents
 */
public static void validate( String xmlDokument, Source[] xsdSchema ) throws SAXException, IOException {   
  SchemaFactory schemaFactory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI );
  Schema schema = schemaFactory.newSchema( xsdSchema );
  Validator validator = schema.newValidator();
  validator.setErrorHandler( new MyErrorHandler() );
  validator.validate( new StreamSource(new File(xmlDokument)) );
}

最小例子:

主要架构:

<xs:schema
    xmlns="baseNamespace"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="baseNamespace"
    xmlns:tns="baseNamespace">

<!-- Define single tag "baseTag" -->
<xs:element name="baseTag">
  <xs:complexType>
    <xs:sequence>
      <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
</xs:schema>

辅助架构:

<xs:schema
    xmlns="secondaryNamespace"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="secondaryNamespace"
    xmlns:tns="secondaryNamespace"
    elementFormDefault="qualified"
    attributeFormDefault="qualified">

<xs:element name="additionalTag"/>

</xs:schema>

我想验证的XML文档:

<baseTag
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="baseNamespace"
  xmlns:secondary="secondaryNamespace"
  xsi:schemaLocation="
    baseNamespace base.xsd
    secondaryNamespace secondary.xsd">

  <secondary:additionalTag/>
  <secondary:invalidTag/>
</baseTag>

使用上面给出两个模式文档的Java代码不会产生任何验证错误,只有当我将基础模式中的lax更改为strict时(我不想要)。这种情况下的错误消息是

cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'secondary:invalidTag'.

问题:

我是否误解了某些内容,这实际上是正确的行为吗?或者我对processContents

是对的

我的架构文档做得对吗?

我的Java代码是否正确?我怎么能改变它以使其表现如预期?

1 个答案:

答案 0 :(得分:6)

根据规范:

“它将验证可以获取架构信息的元素和属性,但它不会为那些无法获取任何架构信息的人发出错误信号。”

因此,当您使用procesContents“lax”时,验证程序无法找到“invalidTag”的架构,因此根据规范忽略它。