我有一个简单的表单,有一些日期字段和单选按钮。其中一个元素有一个相关的规则,它依赖于前两个问题,其中一个是单选按钮,另一个是日期字段。 我在这里创建了一个简单的例子,可以直接在Orbeon中运行:
<xh:html xmlns:xh="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:exf="http://www.exforms.org/exf/1-0"
xmlns:fb="http://orbeon.org/oxf/xml/form-builder"
xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
xmlns:saxon="http://saxon.sf.net/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:sql="http://orbeon.org/oxf/xml/sql"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
xmlns:xxi="http://orbeon.org/oxf/xml/xinclude">
<xh:head>
<xh:meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
<xh:title>DateTest</xh:title>
<xf:model id="fr-form-model" xxf:expose-xpath-types="true">
<xf:instance xxf:readonly="true" id="fr-form-metadata" xxf:exclude-result-prefixes="#all">
<metadata>
<application-name>WebForms</application-name>
<form-name>DateTest_v1</form-name>
<title xml:lang="en">DateTest</title>
<description xml:lang="en">Version: 1. Modification date: 2015-05-27 14:43:59. Publication date: 2015-05-27 14:43:59.</description>
<singleton>false</singleton>
</metadata>
</xf:instance>
<xf:instance id="fr-form-instance">
<form>
<Category>
<Question1/>
<Question2/>
<Question3/>
<Question4/>
</Category>
</form>
</xf:instance>
<xf:bind id="fr-form-binds" ref="instance('fr-form-instance')">
<xf:bind id="Category-bind" name="Category" ref="/form/Category">
<xf:bind id="Question1-bind" name="Question1" ref="Question1" required="true()"/>
<xf:bind id="Question2-bind" name="Question2" readonly="false" ref="Question2"
relevant="(( $Question1='Answer' ) )"
required="true()"
type="xf:date"/>
<xf:bind id="Question3-bind" name="Question3" readonly="false" ref="Question3"
relevant="(( $Question1='Answer' and string-length($Question1/text()) > 0 ) )"
required="true()"
type="xf:date"/>
<xf:bind id="Question4-bind" name="Question4" readonly="false" ref="Question4"
relevant="(( xs:date($Question2) > xs:date('2015-05-20')) or ( $Question1='Answer2' ) )"
required="true()"/>
</xf:bind>
</xf:bind>
<xf:instance id="fr-form-attachments">
<attachments>
<css filename="" mediatype="text/css" size=""/>
<pdf filename="" mediatype="application/pdf" size=""/>
</attachments>
</xf:instance>
<xf:instance id="fr-form-resources" xxf:readonly="false">
<resources>
<resource xml:lang="en">
<Category>
<label>Category</label>
<hint/>
<alert/>
<Question1>
<label>Question1</label>
<hint/>
<alert/>
<item>
<label>Answer</label>
<hint/>
<value>Answer</value>
</item>
<item>
<label>Answer2</label>
<hint/>
<value>Answer2</value>
</item>
</Question1>
<Question2>
<label>Question2</label>
<hint/>
<alert/>
</Question2>
<Question3>
<label>Question3</label>
<hint/>
<alert/>
</Question3>
<Question4>
<label>Question4</label>
<hint/>
<alert/>
<item>
<label>Answer</label>
<hint/>
<value>Answer</value>
</item>
<item>
<label>Answer2</label>
<hint/>
<value>Answer2</value>
</item>
</Question4>
</Category>
</resource>
</resources>
</xf:instance>
<xf:instance id="fr-service-response-instance" xxf:exclude-result-prefixes="#all">
<response/>
</xf:instance>
</xf:model>
</xh:head>
<xh:body>
<fr:view>
<fr:body xmlns:xbl="http://www.w3.org/ns/xbl"
xmlns:oxf="http://www.orbeon.com/oxf/processors"
xmlns:p="http://www.orbeon.com/oxf/pipeline"
xmlns:dataModel="java:org.orbeon.oxf.fb.DataModel">
<fr:section bind="Category-bind" class="webforms-element webforms-category"
id="Category-control">
<xf:label mediatype="text/html" ref="$form-resources/Category/label"/>
<xf:hint ref="$form-resources/Category/hint"/>
<xf:alert ref="$form-resources/Category/alert"/>
<xh:tr>
<xh:td>
<xf:select1 appearance="full" bind="Question1-bind"
class="webforms-element webforms-question"
id="Question1-control">
<xf:label mediatype="text/html" ref="$form-resources/Category/Question1/label"/>
<xf:hint ref="$form-resources/Category/Question1/hint"/>
<xf:alert ref="$form-resources/Category/Question1/alert"/>
<xf:itemset class="webforms-element webforms-answer"
ref="$form-resources/Category/Question1/item">
<xf:label ref="label"/>
<xf:value ref="value"/>
<xf:hint ref="hint"/>
</xf:itemset>
</xf:select1>
</xh:td>
</xh:tr>
<xh:tr>
<xh:td>
<xf:input bind="Question2-bind" class="webforms-element webforms-question"
id="Question2-control">
<xf:label mediatype="text/html" ref="$form-resources/Category/Question2/label"/>
<xf:hint ref="$form-resources/Category/Question2/hint"/>
<xf:alert ref="$form-resources/Category/Question2/alert"/>
</xf:input>
</xh:td>
</xh:tr>
<xh:tr>
<xh:td>
<xf:input bind="Question3-bind" class="webforms-element webforms-question"
id="Question3-control">
<xf:label mediatype="text/html" ref="$form-resources/Category/Question3/label"/>
<xf:hint ref="$form-resources/Category/Question3/hint"/>
<xf:alert ref="$form-resources/Category/Question3/alert"/>
</xf:input>
</xh:td>
</xh:tr>
<xh:tr>
<xh:td>
<xf:select1 appearance="full" bind="Question4-bind"
class="webforms-element webforms-question"
id="Question4-control">
<xf:label mediatype="text/html" ref="$form-resources/Category/Question4/label"/>
<xf:hint ref="$form-resources/Category/Question4/hint"/>
<xf:alert ref="$form-resources/Category/Question4/alert"/>
<xf:itemset class="webforms-element webforms-answer"
ref="$form-resources/Category/Question4/item">
<xf:label ref="label"/>
<xf:value ref="value"/>
<xf:hint ref="hint"/>
</xf:itemset>
</xf:select1>
</xh:td>
</xh:tr>
</fr:section>
</fr:body>
</fr:view>
</xh:body>
</xh:html>
有趣的是问题4,其中包含相关规则(( xs:date($Question2) > xs:date('2015-05-20')) or ($Question1='Answer2'))
。
如果我在OR运算符中首先写入xs:date($Question2) > xs:date('2015-05-20')
的部分以及$Question1='Answer2'
的部分,则Question1
选择Answer2
时,不会显示问题4。这意味着忽略OR运算符的右侧部分。但是,如果我将相关规则更改为(( $Question1='Answer2') or (xs:date($Question2) > xs:date('2015-05-20')))
,则在两种情况下行为都会完美:如果Question1 = answer或者date字段具有正确的值,则显示Question4。
似乎在第一时间拥有约会给我一些问题。可能是因为如果问题3由于流量而未填满,则日期为空值且相关规则未正确运行。
我还尝试了一些替代方法,即检查字段的长度,添加string-length(format-date($Question3), '[MNn,*-3]/[D01]/[Y]')) > 0
或if(not(normalize-space($Question2) = '')) then ( xs:date($Question2) > xs:date('2015-05-20')) else false
两者的范围是忽略日期字段操作符的处理(如果它为空)。但是没有运气。
对于其他不同类型的日期,相关规则正常工作,因此我认为问题出在我的日期字段中。
如果这是预期的行为,问题是:如何以正确的方式使用日期字段以使相关规则正常工作?
答案 0 :(得分:1)
首先,当xs:date($foo)
是foo
的日期时,您不需要使用$Question2 > xs:date('2015-05-20')
type annotations enabled,这是您在表单生成器中创建的表单的默认设置。但是这对你的情况没有多大帮助,因为评估$Question2
时,如果xs:date($Question2)
不是日期,整个表达式将会失败,就像你写了$Question2 castable as xs:date and $Question2 > xs:date('2015-05-20')
一样。所以在你的情况下,你需要:
$Question2
,因此当$Question2
不是日期时,表达式的这一部分不会失败,但会返回false。我们已经看到了这个问题的几个变体,我们当前认为我们可以通过更改XForms引擎来解决这个问题,当访问$Question2
的类型值时{{1}不是日期(或者它应该是什么类型)。这相当于() > xs:date('2015-05-20')
,它返回false,并且适用于您的情况。如果您有兴趣,可在RFE 2251中详细介绍。但同样,现在,你将不得不求助于上述两种技术之一。