Итак, есть схема 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>