Проверка XML в Java: processContents = "lax" не работает должным образом - PullRequest
5 голосов
/ 19 октября 2011

У меня есть XML-схема, которая содержит число

<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 Ответ

6 голосов
/ 19 октября 2011

В соответствии со спецификацией:

"Он будет проверять элементы и атрибуты, для которых он может получать информацию о схеме, но не будет сигнализировать об ошибках для тех, кому не удается получить информацию о схеме."

Таким образом, когда вы используете processContents «lax», валидатор не может найти схему для «invalidTag» и, следовательно, игнорирует ее согласно спецификации.

...