使用输入xsd模式验证XSL文档选择和匹配属性

时间:2013-12-12 13:27:12

标签: xml xslt xsd xsd-validation

是否有可能针对输入数据XSD架构验证XSLT“select”和“match”(可能还有更多)属性?

例如,如果我的XSD架构定义了名为“realRoot”的输入XML根元素

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

  <xs:element name="realRoot" type="rootType"/>

  <xs:complexType name="rootType">
    <xs:sequence>
      ...
    </xs:sequence>
  </xs:complexType>
</xs:schema>

然后是XSL

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xsl:my="http://example.org/my-schema"
  xsi:schemaLocation="http://example.org/my-schema my-schema.xsd">

  <xsl:template match="/my:fakeRoot">
    ...
  </xsl:template>

</xsl:stylesheet>

会快速失败,因为架构中没有定义fakeRoot元素。

它可以帮助更快地发现错误,可以更轻松地重构XML模式,并在IDE中为这些XSLT属性实现自动完成。

2 个答案:

答案 0 :(得分:4)

是的,原则上是可能的。在实践中,我不知道任何执行此类分析的XSLT处理器,当我听到关于此类事情的研究论文时,我总是带走的信息是“哇,快速复杂!”

一些复杂因素:

  • XSD没有提供明确的方法来将特定的顶级元素标识为潜在的文档根元素,因此您想象的故事的前提已经有点不确定了。

  • XSLT旨在与任何格式良好的XML(或严格来说,XSLT处理器可以读取的XPath数据模型的任何实例化)一起工作,因此样式表可以仅在输入中假定输入的有效性特殊操作模式,未在规范中定义。

  • XSLT中模板驱动的控制流使得很难生成可能的输入节点的严格描述,这些节点在评估特定模板时是最新的;结果是一个非常大的可能状态空间,这使得很难为处理器可以利用的模式产生良好的保证。

所有这一切,处理器肯定可以查看匹配模式并在样式表中选择表达式,并为每一个说明,它是否原则上可以匹配输入文档中对给定模式有效的任何节点。这将更容易处理,可能仍然有用,并可能成为一个好的学生项目。

答案 1 :(得分:3)

Saxon-EE,打开了架构感知,将检查您的选择表达式并根据架构匹配模式。但是,它需要比你建议的更多调整。

写入<xsl:template match="/my:fakeRoot">不会被拒绝,即使模式中没有fakeRoot元素,因为样式表创建对模式无效的元素然后处理它们是完全合法的(也许使它们有效)。但是,如果您将其写为<xsl:template match="/schema-element(my:fakeRoot)">,它将被拒绝,因为您编写的模式只匹配模式中定义的元素。类似地,只有声明了$ x的类型时才会拒绝像$ x // svg:polygno(带有拼写错误的元素名称)这样的表达式,例如使用as =“schema-element(svg)”

XSLT 3.0中有一个新选项(新草案刚出来)(尚未在Saxon中实现)

将导致<xsl:template match="/my:fakeRoot"><xsl:template match="/schema-element(my:fakeRoot)">具有相同的含义,因此如果架构中没有此名称的元素,则会被拒绝。当然它也适用于更复杂的模式,例如,如果td不能作为表的子项出现,则匹配=“table / td”将被拒绝。

我使用模式感知样式表开发的经验是,它可以使调试变得更加容易,特别是如果您正在使用非常复杂的词汇表。但是,在声明所有类型时会有前期成本,这意味着许多人无法获得全部收益。希望新的选项将使其更容易访问。