XSD: XML-файлы проходят проверку, но также и XSL и XSD. - PullRequest
0 голосов
/ 21 января 2010

Итак, есть схема XSD, которая проверяет файл данных. Он объявляет корневой элемент документа, а затем идет complexType, которые описывают структуру. Схема имеет пустое целевое пространство имен, узлы документа не должны определяться пространством имен.

Недавно кто-то по ошибке отправил шаблон XSL вместо файла данных XML. Этот xsl прошел проверку без проблем и поэтому был направлен на процессор XSLT. Результатом был в основном текст в свободной форме, найденный в проверенном XSL.

Затем мы отправили всевозможные документы XML в валидатор (например, различные схемы XSD и шаблоны XSL), и все они прошли проверку.

Мы использовали разные способы проверки (XPathDocument.CheckValidity и XMLDocument.Validate), без разницы.

Что происходит в любом случае? Готова ли наша схема проверки пропустить какие-либо документы, корневые узлы которых квалифицированы в пространство имен, отличное от того, что описывает схема? Как мы можем предотвратить это?

EDIT

Код проверки (версия 1):

Dim data As XPathDocument
....
If Not data.CreateNavigator.CheckValidity(ValidationSchemaSet, AddressOf vh.ValidationHandler) Then
    result = "Validation failed." & ControlChars.NewLine & String.Join(ControlChars.NewLine, vh.Messages.ToArray)
    Return False
End If

, где vh:

Private Class VHandler
    Public Messages As New List(Of String)

    Public Sub ValidationHandler(ByVal sender As Object, ByVal e As ValidationEventArgs)
        If e.Severity = XmlSeverityType.Error Then
            Messages.Add(e.Message)
        End If
    End Sub
End Class

XSD-схема:

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

  <xs:include schemaLocation="CarrierLabel_Type_1.xsd" />
  <xs:include schemaLocation="CarrierLabel_Type_2.xsd" />
  <xs:include schemaLocation="CarrierLabel_Type_3.xsd" />

  <!-- Schema definition -->
  <xs:element name="PrintJob" type="printJobType" />


  <!-- Types declaration -->
  <xs:simpleType name="nonEmptyString">
    <xs:restriction base="xs:string">
      <xs:minLength value="1"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:complexType name="printJobType">
    <xs:sequence minOccurs="1" maxOccurs="unbounded">
      <xs:choice>
        <xs:element name="CarrierLabel_type_1" type="CarrierLabel_type_1" />
        <xs:element name="CarrierLabel_type_2" type="CarrierLabel_type_2" />
        <xs:element name="CarrierLabel_type_3" type="CarrierLabel_type_3" />
      </xs:choice>
    </xs:sequence>

    <xs:attribute name="printer" type="nonEmptyString" use="required" />
    <xs:attribute name="res" type="xs:positiveInteger" use="required" />
  </xs:complexType>

</xs:schema>

Должен (и будет) проходить:

<?xml version='1.0' encoding='utf-8'?>
<PrintJob printer="printer_1" res="200">
  <CarrierLabel_type_1>
    <print_job_id>123456</print_job_id>
    <notes></notes>
    <labels_count>1</labels_count>
    <cases_indicator>2xCASE</cases_indicator>
  </CarrierLabel_type_1>
  <CarrierLabel_type_2>
    <next_location>Go there now!</next_location>
  </CarrierLabel_type_2>
</PrintJob>

Не должно пройти, но ПРОЙДЕТ КАК ДЕЙСТВИТЕЛЬНЫЕ ДАННЫЕ:

<?xml version='1.0' encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="text"/>

  <xsl:template match="WrongLabel">
    <xsl:param name="context"/>
    <xsl:param name="res"/>
    WRONG LABEL
  </xsl:template>

</xsl:stylesheet>

Ответы [ 4 ]

1 голос
/ 21 января 2010

XML-схемы действительно проверяют элементы в пространстве имен, а не документы. Нет правила XML-схемы, которое говорит, что элемент верхнего уровня документа экземпляра должен находиться в определенном пространстве имен. Это согласуется с общей идеей о том, что пространство имен - это его собственный маленький мир, и мешает мне написать схему в моем пространстве имен, которая сделает ваши документы недействительными. Если элемент не находится в моем пространстве имен, это не мое дело

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

0 голосов
/ 21 января 2010

Насколько я понимаю, XML-схема (XSD) не позволяет требовать, чтобы корневой узел документа представлял собой определенный элемент - единственный способ сделать это - ограничить элементы, определенные на «глобальном уровне». только один элемент. Возможно ли, что ваш код проверки импортирует схему для XSLT, так что когда он видит документ XSLT, он проверяет, потому что элементы XSLT были определены на глобальном уровне.

0 голосов
/ 21 января 2010

правый.

Оказалось, проверка имеет три возможных результата, а не два - действительный, недействительный и неизвестный. Поэтому логическое возвращаемое значение функции CheckValidity несколько удивительно.

Если корневой узел документа не описан схемой, документ проходит проверку без ошибок, и никаких событий проверки не происходит, но корневой узел получает статус «неизвестно». Для нашей цели это провал. Поэтому нам также необходимо проверить элемент XMLNode.SchemaInfo.Validity корневого узла.

Хотелось бы, чтобы Validate() документация по методу была немного понятнее.

0 голосов
/ 21 января 2010

Не увидев никакого кода, я собираюсь сделать удар и предположить, что он просто может быть, потому что ваша проверка устанавливает ValidationType для объекта XmlReaderSettings, но либо не подключать ValidationEventHandler для проверки ошибок проверки, либо просто ничего не делать с этими событиями проверки.

Даже с XmlDocument.Validate вам нужно подключить этот ValidationEventHandler.

См. MSDN здесь .

...