如何使用日期格式的输入字段在另一个元素的相关规则中可以为null?

时间:2015-05-27 15:16:39

标签: orbeon xforms

我有一个简单的表单,有一些日期字段和单选按钮。其中一个元素有一个相关的规则,它依赖于前两个问题,其中一个是单选按钮,另一个是日期字段。 我在这里创建了一个简单的例子,可以直接在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()) &gt; 0 ) )"
                 required="true()"
                 type="xf:date"/>
            <xf:bind id="Question4-bind" name="Question4" readonly="false" ref="Question4"
                 relevant="(( xs:date($Question2) &gt; 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) &gt; xs:date('2015-05-20'))),则在两种情况下行为都会完美:如果Question1 = answer或者date字段具有正确的值,则显示Question4。

似乎在第一时间拥有约会给我一些问题。可能是因为如果问题3由于流量而未填满,则日期为空值且相关规则未正确运行

我还尝试了一些替代方法,即检查字段的长度,添加string-length(format-date($Question3), '[MNn,*-3]/[D01]/[Y]')) > 0if(not(normalize-space($Question2) = '')) then ( xs:date($Question2) &gt; xs:date('2015-05-20')) else false两者的范围是忽略日期字段操作符的处理(如果它为空)。但是没有运气。

对于其他不同类型的日期,相关规则正常工作,因此我认为问题出在我的日期字段中。

如果这是预期的行为,问题是:如何以正确的方式使用日期字段以使相关规则正常工作?

1 个答案:

答案 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中详细介绍。但同样,现在,你将不得不求助于上述两种技术之一。