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

Phi*_*ler 5 java xml xsd sax

我有一个XML Schema,其中包含许多

<any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
Run Code Online (Sandbox Code Playgroud)

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

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

但是,似乎Java XML验证程序忽略了这些错误.我已经验证了解析器具有执行验证所需的所有模式文档(如果我将XML模式更改为processContents="strict",它按预期工作并使用辅助模式文档进行验证).似乎验证器的行为就像使用value指定了属性一样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)) );
}
Run Code Online (Sandbox Code Playgroud)

最小的例子:

主要架构:

<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>
Run Code Online (Sandbox Code Playgroud)

辅助架构:

<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>
Run Code Online (Sandbox Code Playgroud)

我试图验证的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>
Run Code Online (Sandbox Code Playgroud)

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

cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'secondary:invalidTag'.
Run Code Online (Sandbox Code Playgroud)

问题:

我误解了什么,这实际上是正确的行为吗?或者我是对的processContents吗?

我的架构文档是否做得对吗?

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

jta*_*orn 6

根据规格:

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

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

  • 不,它不是基于是否存在命名空间的模式定义,而是基于是否存在特定元素名称的元素声明. (3认同)