XSD:XML 文件通过验证,但 XSL 和 XSD 也一样 [英] XSD: XML files pass validation, but so do XSLs and XSDs

查看:15
本文介绍了XSD:XML 文件通过验证,但 XSL 和 XSD 也一样的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以有一个 XSD 架构可以验证数据文件.它声明文档的根元素,然后转到描述结构的complexType.架构的目标命名空间为空,文档节点不应使用命名空间进行限定.

So there's an XSD schema that validates a data file. It declares root element of the document, and then go complexType's that describe structure. The schema has empty target namespace, document nodes are not supposed to be qualified with a namespace.

最近有人错误地发送了 XSL 模板来代替 XML 数据文件.该 xsl 通过验证没有问题,因此被定向到 XSLT 处理器.结果基本上是在经过验证的 XSL 中找到的自由格式文本.

Recently someone by mistake sent an XSL template in place of an XML data file. That xsl passed validation no problem and was therefore directed to the XSLT processor. Result was basically the free-form text found in the validated XSL.

然后我们将各种 XML 文档发送到验证器(例如各种 XSD 模式和 XSL 模板),它们都通过了验证.

We then sent all sorts of XML documents to the validator (like, various XSD schemas and XSL templates), and they all passed validation.

我们尝试了不同的验证方式(XPathDocument.CheckValidity 和 XMLDocument.Validate),没有区别.

We tried different ways of validation (XPathDocument.CheckValidity and XMLDocument.Validate), no difference.

到底发生了什么?我们的验证模式是否乐意将根节点限定到与模式描述不同的命名空间的任何文档传递?我们如何防止这种情况发生?

What is happening anyway? Is our validation schema happy to pass any documents whose root nodes are qualified to a namespace different to what the schema describes? How do we prevent that?

编辑

验证码(版本 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>

推荐答案

XML 模式真正验证的是命名空间中的元素,而不是文档.没有 XML Schema 规则规定实例文档的顶级元素必须位于特定命名空间内.这符合命名空间是它自己的小世界的一般想法,它阻止我在我的命名空间中编写一个模式,这将使你的文档无效.如果一个元素不在我的命名空间中,那不关我的事

XML schemas really validate elements within a namespace, not documents. There's no XML Schema rule that says that the top-level element of the instance document must be within a specific namespace. This fits in with the general idea that a namespace is its own little world, and it prevents me from writing a schema in my namespace that will invalidate documents in yours. If an element's not in my namespace, it's none of my business

这意味着在验证实例文档时,您必须检查以确保您正在验证的文档的顶级元素位于您的应用程序接受的命名空间中 - 在您的应用程序中,这只是默认值命名空间.

This means that when validating instance documents, you have to check to make sure that the top-level element of the document you're validating is in a namespace that your application accepts - which, in your application, is simply the default namespace.

这篇关于XSD:XML 文件通过验证,但 XSL 和 XSD 也一样的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆