如何断言元素值是某种类型?

时间:2012-12-30 15:04:55

标签: xml xslt

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

4 个答案:

答案 0 :(得分:1)

可以使用FXSL库的f: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(),从 its source 可以看出,内部使用了XPath 2.0运算符instance of,并测试了从最常见类型到更具体类型的值直到确定特定类型。

答案 1 :(得分:0)

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

  

xs:integer

的5个实例

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

有关其他信息,请查看this

答案 2 :(得分:0)

使用模式感知XSLT 2.0处理器(如Saxon 9的企业版或类似XmlPrime或AltovaXML),您可以使用W3C XML模式在使用XSLT处理输入文档时对其进行验证。

答案 3 :(得分:0)

使用cast as运算符,例如

'5' cast as xs:integer返回5

'foo' cast as xs:integer使用Saxon抛出Cannot convert string "d" to an integer

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

if (not('foo' castable as xs:integer)) then
   error((), 'bad')