Xml xsl:variable上SequenceType的schema-element()和文字结果元素

Xml xsl:variable上SequenceType的schema-element()和文字结果元素,xml,xslt,xsd,xslt-2.0,Xml,Xslt,Xsd,Xslt 2.0,我试图理解schema-element()作为带有文本结果元素的SequenceType时是如何工作的。这是我的样式表 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"> <xsl:import-schem

我试图理解
schema-element()
作为带有文本结果元素的
SequenceType
时是如何工作的。这是我的样式表

<xsl:stylesheet
  version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs">

  <xsl:import-schema>
    <xs:schema>
      <xs:element name="foo">
        <xs:complexType>
          <xs:attribute name="bar"/>
        </xs:complexType>
      </xs:element>
    </xs:schema>
  </xsl:import-schema>

  <xsl:variable name="test" as="schema-element(foo)">
    <foo bar="baz"/>
  </xsl:variable>

  <xsl:template match="/">
    <xsl:sequence select="$test"/>
  </xsl:template>

</xsl:stylesheet>

Saxon EE 9.4.0.4(在Oxygen 14.1中)给了我以下编译错误
变量$test的值的必需项类型是schema元素(foo);提供的值具有项目类型元素(foo{http://www.w3.org/2001/XMLSchema}未键入)

在SequenceType中使用构造«模式元素(N)»…时, 那么N必须是全局元素的名称…声明中的 导入的架构

同一来源的其他地方

«as=“schema element(EVENT)”»表示[参数]必须是验证为有效的元素节点 事件或事件替换组中的元素


似乎导入的模式应该将
验证为
foo
元素
@xsl:type
似乎会有所帮助,但前提是在导入的模式中有一个命名的复杂类型。我遗漏了什么或做错了什么?

您是否尝试过使用
?错误消息表明结果元素是在没有类型注释的情况下创建的,因此可能需要显式请求验证,
as
属性可能不够。但是我对支持模式的XSLT2.0不太熟悉,因此建议您尝试一下。

一个复杂的问题是,当xsl:variable包含文本内容时,变量绑定到文档节点(当然,稍后可能会以各种方式将值强制为其他类型)。在Michael Kay的书的第4章中关于验证临时树的讨论中,您将发现一个有益的建议,即在xsl:document指令中使用validation属性包装“foo”元素。出于稍后将变得清晰的原因,我重命名了变量:

<xsl:variable name="test0">
  <xsl:document validation="strict">
    <foo bar="baz"/>      
  </xsl:document>
</xsl:variable>

可能有一种更简洁的方法来解决这个问题,不需要两步定义,但它确实可以在没有错误消息的情况下工作。

这会清除编译错误,但会给出运行时验证错误
属性@xsl:validation不允许对元素进行验证
。我想这会好一些,但似乎仍然不太理想。啊,在读了这一章之后,@c-m-sperberg-mcqueen指出我发现了我做错了什么。这个解决方案是正确的,但是我让saxon进行输入验证,并且我对自己运行样式表,因此触发了错误。我希望我也能接受这个答案,因为指向第4章的指针非常有用。
<xsl:variable name="test" 
              as="schema-element(foo)" 
              select="$test0/foo"/>