</xsl:template>
with this single template, our "schema" would accept any well formed xml document and never raise any error and we need to add templates to define what's forbidden.
有了这个简单的模板,我们的 "schema" 将接受任何合式的 xml 文档,不会抛出任何错误并且我们需要添加模板来定义什么是被禁止的。
like with the design of any xslt transformation, we have the choice to implement the tests as conditions in the "match" attribute of templates or within the templates using if or choose statements. when we are using if or choose statements, we have also the choice of the location where we will will do the test.
像任何一个 xslt 转换的设计一样,我们可以选择把这个测试实现为在模板的 "match" 属性之中或者在模板之中使用 if 或者 choose 语句。当我们使用 if 或者 choose 语句的时候,我们还可以决定哪儿进行这样的测试。
to check that the document element is "library", we can for instance:
为了检查文档元素是 "library",我可以这样:
now that we've set up the background, we can generalize it and a pretty much complete "schema" including a test for unicity of the identifiers could be:
现在我们台子搭起来了,归纳一下,一个更完善的包括测试标识符单一性的 "schema" 可能是这样的:
note that we have left a degree of opening and that arbitrary element and text nodes can be added to the book element.
注意,我们留下了一定程度的扩展机会,任意元素和文本都能被添加到 book 元素之中。
2.1.1.1. 在 match 表达式中测试
we can write a template to allow library as document element:
我们可以编写一个模板来允许 library 作为文档元素:
<xsl:template match="/library">
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>
but we also need to forbid other document elements:
但是我们还需要禁止其他的文档元素:
<xsl:template match="/*">
<xsl:message terminate="no">
the document element should be "library".
</xsl:message>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>
or, alternatively, we can rely on the default template and replace both templates by a slightly more complex match expression:
或者,我们还能依赖缺省模板并且把两个模板换成一个 match 表达式稍微复杂一些的模板:
<xsl:template match="/*[not(self::library)]">
<xsl:message terminate="no">
the document element should be "library".
</xsl:message>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>
2.1.1.2. 在模板中测试
we can also perform the test in a template for the root of the document:
我们还能在模板中执行对文档的根的测试:
<xsl:template match="/">
<xsl:if test="not(library)">
<xsl:message terminate="no">
the document element should be "library".
</xsl:message>
</xsl:if>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>
or do the same test in a template for document element:
或者在模板中对模板元素进行相同测试:
<xsl:template match="/*">
<xsl:if test="not(self::library)">
<xsl:message terminate="no">
the document element should be "library".
</xsl:message>
</xsl:if>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>
2.1.1.3. 完整的 xslt 实现的开放 schema
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" >
<xsl:template match="*|@*|text()">
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>
<xsl:template match="/*[not(self::library)]">
<xsl:message terminate="no">
<xsl:text>the document element should be "library", not "</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>"!</xsl:text>
</xsl:message>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>
<xsl:template match="/*/*[not(self::book)]">
<xsl:message terminate="no">
<xsl:text>the children elements of library should be "book", not "</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text>"!</xsl:text>
</xsl:message>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>
<xsl:template match="library/@*">
<xsl:message terminate="no">
<xsl:text>the "library" element should have no attribute, </xsl:text>
<xsl:value-of select="name()"/>
<xsl:text> shouldn't appear!</xsl:text>
</xsl:message>