1

有没有一种好方法可以断言当前元素的值必须是某种类型(例如 xs:integer),如果不是则抛出异常?使用 XSL 2.0

4

4 回答 4

1

可以使用FXSLf:type()库的功能来动态确定变量/值的类型

这是 FXSL 中的测试转换f:type()

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:f="http://fxsl.sf.net/"
 exclude-result-prefixes="f xs"
 >
  <xsl:import href="../f/func-type.xsl"/>

  <!-- To be applied on ../data/numList.xml -->

  <xsl:output omit-xml-declaration="yes"/>

  <xsl:template match="/">
    f:apply(f:typeConstructor(11),'03'): <xsl:value-of select="f:apply(f:typeConstructor(11),'03')"/>
    f:apply(f:typeConstructor('xxx'),'03'): <xsl:value-of select="f:apply(f:typeConstructor('xxx'),'03')"/>
    f:apply(f:typeConstructor(11),'03') gt 4: <xsl:value-of select="f:apply(f:typeConstructor(11),'03') gt 4"/>
    f:type(f:apply(f:typeConstructor(11),'03')): <xsl:value-of select="f:type(f:apply(f:typeConstructor(11),'03'))"/>
    f:type(f:apply(f:typeConstructor('string'), 3)): <xsl:value-of select="f:type(f:apply(f:typeConstructor('string'),'03'))"/>
<!--  Supported only by a SA Processor -->
    xs:token('abc') : <xsl:value-of  select="f:type(xs:token('abc'))"
       use-when="system-property('xsl:is-schema-aware')='yes'"/>

    -1 : <xsl:value-of select="f:type(-1)"/>
<!--  Supported only by a SA Processor -->
    xs:negativeInteger(-1) : <xsl:value-of select="f:type(xs:negativeInteger(-1))"
       use-when="system-property('xsl:is-schema-aware')='yes'" />
    xs:nonPositiveInteger(0) : <xsl:value-of select="f:type(xs:nonPositiveInteger(0))"
       use-when="system-property('xsl:is-schema-aware')='yes'" />

    0 : <xsl:value-of select="f:type(0)"/>
    3 : <xsl:value-of select="f:type(3)"/>
    3. : <xsl:value-of select="f:type(3.)"/>
    3.0E1 : <xsl:value-of select="f:type(3.0E1)"/>
    xs:float(3) : <xsl:value-of select="f:type(xs:float(3))"/>
<!--  Supported only by a SA Processor -->
    xs:positiveInteger(3) : <xsl:value-of select="f:type(xs:positiveInteger(3))"
       use-when="system-property('xsl:is-schema-aware')='yes'" />

   '3' : <xsl:value-of select="f:type('3')"/>
   (/*/*/text())[1] : <xsl:value-of select="f:type((/*/*/text())[1])"/>
   data((/*/*/text())[1]) : <xsl:value-of select="f:type(data((/*/*/text())[1]))"/>
  </xsl:template>
</xsl:stylesheet>

将此转换应用于此 XML 文档时:

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>

产生了想要的、正确的结果:

    f:apply(f:typeConstructor(11),'03'): 3
    f:apply(f:typeConstructor('xxx'),'03'): 03
    f:apply(f:typeConstructor(11),'03') gt 4: false
    f:type(f:apply(f:typeConstructor(11),'03')): xs:integer
    f:type(f:apply(f:typeConstructor('string'), 3)): xs:string

    xs:token('abc') : xs:string

    -1 : xs:integer

    xs:negativeInteger(-1) : xs:integer
    xs:nonPositiveInteger(0) : xs:integer

    0 : xs:integer
    3 : xs:integer
    3. : xs:decimal
    3.0E1 : xs:double
    xs:float(3) : xs:float

    xs:positiveInteger(3) : xs:integer

   '3' : xs:string
   (/*/*/text())[1] : xml:node
   data((/*/*/text())[1]) : xs:string

说明

f:type(),从它的源代码可以看出,它在内部使用 XPath 2.0 运算符instance of并测试从最常见类型到更具体类型的值,直到它确定特定类型。

于 2012-12-30T16:57:03.217 回答
0

使用cast as运算符,例如

'5' cast as xs:integer返回 5

'foo' cast as xs:integerCannot convert string "d" to an integer使用撒克逊人投掷。

如果你想抛出你自己的错误,你可以使用castable as,例如

if (not('foo' castable as xs:integer)) then
   error((), 'bad')
于 2012-12-31T02:57:54.803 回答
0

使用像 Saxon 9 的企业版或像 XmlPrime 或 AltovaXML 这样的模式感知 XSLT 2.0 处理器,您可以在使用 XSLT 处理输入文档时使用 W3C XML 模式来验证输入文档。

于 2012-12-30T16:57:51.547 回答
0

XPath中,您可以instance of这样使用:

xs:integer 的 5 个实例

此示例返回 true,因为给定值是给定类型的实例。

有关其他信息,您可以查看

于 2012-12-30T16:01:27.643 回答