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

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

问题描述

所以这是一个验证的数据文件XSD架构。 它定义了文档的根元素,然后转到复杂类型的描述结构。该架构已空目标命名空间,文档节点不应该有一个命名空间进行限定。

最近有人误到位XML数据文件的发送的XSL模板。这XSL通过验证没有问题,因此是针对XSLT处理器。结果是基本上都在验证XSL中发现的自由格式文本。

我们再发送各种XML文档的验证器(如,各种XSD架构和XSL模板),他们都通过了验证。

我们试图验证不同的方式(XPathDocument.CheckValidity和XMLDocument.Validate),没有什么区别。

这是怎么回事呢?是我们的验证模式传递快乐的根节点有资格不同,以什么样的模式描述了一个命名空间的任何文件?我们如何prevent呢?

修改

验证code(第1版):

 昏暗数据的XPathDocument
....
如果不data.CreateNavigator.CheckValidity(ValidationSchemaSet,AddressOf vh.ValidationHandler)然后
    结果=验证失败。 &放大器; ControlChars.NewLine和放大器;的string.join(ControlChars.NewLine,vh.Messages.ToArray)
    返回False
结束如果
 

,其中VH是:

 专用类VHandler
    公开消息作为新的列表(串)

    公用Sub ValidationHandler(BYVAL发件人为对象,BYVAL E上ValidationEventArgs)
        如果e.Severity = XmlSeverityType.Error然后
            Messages.Add(e.Message)
        结束如果
    结束小组
末级
 

XSD架构:

 < XML版本=1.0编码=UTF-8&GT?;
< XS:模式的xmlns:XS =htt​​p://www.w3.org/2001/XMLSchema>

  < XS:包括的schemaLocation =CarrierLabel_Type_1.xsd/>
  < XS:包括的schemaLocation =CarrierLabel_Type_2.xsd/>
  < XS:包括的schemaLocation =CarrierLabel_Type_3.xsd/>

  <! -  Schema定义 - >
  < XS:元素的名称=PrintJob的TYPE =printJobType/>


  <! - 类型的声明 - >
  < XS:简单类型名称=nonEmptyString>
    < XS:限制基地=XS:字符串>
      < XS:的minLength值=1/>
    < / XS:限制>
  < / XS:简单类型>

  < XS:复杂类型的名称=printJobType>
    &所述; XS:序列的minOccurs =1maxOccurs的=无限>
      < XS:选择>
        < XS:元素的名称=CarrierLabel_type_1TYPE =CarrierLabel_type_1/>
        < XS:元素的名称=CarrierLabel_type_2TYPE =CarrierLabel_type_2/>
        < XS:元素的名称=CarrierLabel_type_3TYPE =CarrierLabel_type_3/>
      < / XS:选择>
    < / XS:序列>

    < XS:属性名=打印机TYPE =nonEmptyString使用=需要/>
    < XS:属性名=资源类型=XS:positiveInteger使用=需要/>
  < / XS:复杂类型>

< / XS:模式>
 

应该(将)通过:

 < XML版本=1.0编码=UTF-8&GT?;
< PrintJob的打印机=printer_1RES =200>
  < CarrierLabel_type_1>
    < print_job_id> 123456< / print_job_id>
    <笔记>< /笔记>
    &其中; labels_count→1&其中; / labels_count>
    < cases_indicator> 2xCASE< / cases_indicator>
  < / CarrierLabel_type_1>
  < CarrierLabel_type_2>
    < next_location>立即前往<!/ next_location>
  < / CarrierLabel_type_2>
< /个PrintJob>
 

不应该通过,但会通过作为有效数据:

 < XML版本=1.0编码=UTF-8&GT?;
< XSL:样式版=1.0的xmlns:XSL =htt​​p://www.w3.org/1999/XSL/Transform>

  < XSL:输出方法=文本/>

  < XSL:模板匹配=WrongLabel>
    < XSL:参数名称=背景/>
    < XSL:参数名称=资源/>
    错标签
  < / XSL:模板>

< / XSL:样式>
 

解决方案

XML Schema真正验证一个命名空间,而不是文件中的元素。有没有XML Schema的规则,即实例文档的顶级元素必须是特定的命名空间内。这符合与一般的想法,一个命名空间是它自己的小世界,而且$ P $从写我的名字空间的模式​​,将在你的无效文件pvents我。如果一个元素是不是在我的空间,这是我的事

这意味着,验证实例文档的时候,你必须检查,以确保您验证文档的顶级元素是在您的应用程序接受一个命名空间 - 这在您的应用程序,只是默认命名空间。

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.

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.

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

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?

EDIT

Validation code (version 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

, where vh is:

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 schema:

<?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>

Should (and will) pass:

<?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>

Should not pass, but WILL PASS AS VALID DATA:

<?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 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天全站免登陆