在XSLT 2.0中将类型转换为字符串布尔值

时间:2015-05-01 19:59:51

标签: xml xslt-2.0 marklogic xsd-validation

我有一个源XML:

<source>
  <a>NONE</a>
  <b>2008-04-10</b>
</source>

我使用XSLT将源XML转换为目标

<?xml version='1.0' ?>
<xsl:stylesheet version="2.0">
<target>
  <d>
    <xsl:value-of select="//source/a"/>
  </d>
  <e>
    <xsl:value-of select="//source/b"/>
  </e>
</target>

我的XSD包含一个定义,即元素'd'必须是布尔值,'e'必须是日期。但是,在使用stylus studio对XSD验证转换的XML时,我收到错误消息

  1. value'NONE'无效boolean
  2. 在dateTime值'2008-04-10'
  3. 中缺少'T'分隔符

    在这种情况下,如何在XSLT中对数据进行类型转换以解决错误?欢迎任何建议。

2 个答案:

答案 0 :(得分:1)

我不认为XSD会在验证其类型之前尝试强制转换值。首先,<xsl:value-of>返回一个字符串,因此对于此示例,您可以使用<xsl:sequence>代替,这将返回表达式的类型。

假设XSD将<d>定义为布尔值,您可以在XSLT中强制转换为布尔值:<xsl:sequence select="//source/a/xs:boolean(.)">但是,如果该表达式返回一个序列并且XSD只是期望一个,则可能会遇到问题单身价值。

假设XSD将<e>定义为xs:dateTime,那么您需要做更多工作才能实现目标,因为2008-04-10不是valid xs:dateTime(这会看起来像2015-05-01T15:29:04.579528-05:00)。 MarkLogic有一个名为xdmp:parse-dateTime的函数,它将转换一个&#34;漂亮的打印&#34;到有效xs:dateTime的时间。假设您使用MarkLogic运行XSLT,您可以强制执行该值:<xsl:sequence select="//source/b/xdmp:parse-dateTime('[Y0001]-[M01]-[D01]', .)">。序列的相同问题适用于此。

答案 1 :(得分:0)

XSD中布尔值的词法空间是truefalse10。必须将其他任何内容转换为精确的4个值之一才能成为有效的布尔值。例如,您可以使用以下表达式(取决于输入语言的详细信息):

if ( a eq 'NONE' ) then 'false' else 'true'

您也可以简单地使用以下内容(假设a不是空序列,该XPath表达式的结果是一个布尔值,而后者将序列化为布尔值的4个词法表示之一,取决于表达式的值):

a ne 'NONE'

根据您的第二个问题,wst是对的,您没有有效的xs:date,而是xs:dateTime。因此,您必须更改架构中的类型(作为日期时间)或者您将值调整为日期时间而不是日期(您将必须决定使用的时间,例如中午或午夜)