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

How to use input fields with date format that can be null in a relevant rule of another element?

我有一个简单的表单,其中包含一些日期字段和单选按钮。其中一个元素有一个相关规则,它依赖于前面两个问题,一个是单选按钮,另一个是日期字段。 我这里创建了一个简单的例子,可以直接在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'))

如果我先写xs:date($Question2) > xs:date('2015-05-20')的部分,然后在OR运算符中写$Question1='Answer2'的部分,当Question1选择了Answer2时,问题4不是显示。这意味着 OR 运算符的右侧部分将被忽略。但是,如果我将相关规则更改为 (( $Question1='Answer2') or (xs:date($Question2) &gt; xs:date('2015-05-20'))),则行为在两种情况下都完美无缺:如果 Question1 = answer 或日期字段具有正确的值,则会显示 Question4。

似乎将日期放在首位给我带来了一些问题。可能是因为如果Question3因流程不填,date为空值,相关规则运行不正确

我也尝试了一些替代方法,例如检查添加 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 的字段的长度,如果它是空的,则忽略日期字段运算符的处理范围。但一点运气都没有。

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

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

首先,当 foo 是日期时,您不需要使用 xs:date($foo)type annotations enabled 现在是您在 Form Builder 中创建的表单的默认值。但这对你的情况没有多大帮助,因为当评估 $Question2 > xs:date('2015-05-20') 时,如果 $Question2 不是日期,整个表达式将失败,就像你写了 xs:date($Question2) .所以在你的情况下,你需要:

  • 首先在复选框上进行测试(您已经知道这行得通)。
  • 写成 $Question2 castable as xs:date and $Question2 > xs:date('2015-05-20'),这样当 $Question2 不是日期时,这部分表达式不会失败,但 return 为 false。

我们已经看到这个问题的几个变体,我们目前认为我们可以通过将 XForms 引擎更改为 return 一个空序列来解决这个问题,当 $Question2 的输入值时被访问并且 $Question2 不是日期(或它应该是的任何类型)。这将等同于 () > xs:date('2015-05-20'),其中 return 是错误的,并且适用于您的情况。如果您有兴趣,RFE 2251 中对此有更详细的介绍。但同样,现在,您将不得不求助于上述两种技术之一。