我有一个使用可重复部分的表单。这在使用表单节点的相对路径时工作正常。问题是我不想强制在表单的节点中使用唯一的名称。一个例子:
<form>
<section-personalData>
<age/>
</section-personalData>
<section-kids-personalData>
<section-kids-personalData-iterator>
<age/>
</section-kids-personalData-iterator>
</section-kids-personalData>
</form>
在此示例中,由于元素<age>
处于不同的级别,因此允许具有相同的名称。当然,为了允许它,在定义节点的<bind>
部分时,我需要指定节点的完整路径以避免混淆。
<xf:bind id="age-bind" name="age" ref="/form/section-personalData/age" required="true()"/>
这是正常的。问题在于可重复部分内部的元素。
<xf:bind id="age-1-bind" name="age-1" ref="/form/section-kids-personalData/section-kids-personalData-iterator/age" required="true()"/>
这几乎可以工作,但我发现了一个意想不到的行为。当您有多个迭代并回答age
值时,所有迭代总是具有相同的答案(当您更改其中一个时,ALL将被更改)。我用输入字段,单选按钮,......进行了实验。
使用Orbeon Builder时,所有元素必须具有唯一名称。但是由于客户端的限制,我们感兴趣的是在两个元素中都有相同的名称。
我复制了一个可以在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>Loop</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>Loop_v1</form-name>
<title xml:lang="en">Loop</title>
<description xml:lang="en">Version: 1. Modification date: 2014-12-04 10:06:03. Publication date: 2014-12-04 10:52:43.</description>
</metadata>
</xf:instance>
<xf:instance id="fr-form-instance">
<form>
<Category1>
<Loop>
<Loop-iterator>
<Question/>
</Loop-iterator>
</Loop>
</Category1>
</form>
</xf:instance>
<xf:bind id="fr-form-binds" ref="instance('fr-form-instance')">
<xf:bind id="Category1-bind" name="Category1" ref="/form/Category1">
<xf:bind id="Loop-bind" name="Loop" ref="/form/Category1/Loop">
<xf:bind id="Loop-iterator-bind" name="Loop-iterator"
ref="/form/Category1/Loop/Loop-iterator">
<xf:bind id="Question-bind" name="Question"
ref="/form/Category1/Loop/Loop-iterator/Question"
required="true()"/>
</xf:bind>
</xf:bind>
</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">
<Category1>
<label>Category1</label>
<hint/>
<alert/>
<Loop>
<label>Loop</label>
<hint/>
<alert/>
<Question>
<label>Question</label>
<hint/>
<alert/>
<item>
<label>Answer</label>
<hint/>
<value>Answer</value>
</item>
<item>
<label>Answer2</label>
<hint/>
<value>Answer2</value>
</item>
<item>
<label>Answer3</label>
<hint/>
<value>Answer3</value>
</item>
</Question>
</Loop>
</Category1>
</resource>
</resources>
</xf:instance>
<xf:instance id="fr-service-response-instance" xxf:exclude-result-prefixes="#all">
<response/>
</xf:instance>
<xf:instance xxf:readonly="true" id="Loop-template">
<Loop-iterator>
<Question/>
</Loop-iterator>
</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="Category1-bind" id="Category1-control">
<xf:label mediatype="text/html" ref="$form-resources/Category1/label"/>
<xf:hint ref="$form-resources/Category1/hint"/>
<xf:alert ref="$form-resources/Category1/alert"/>
<fr:section bind="Loop-bind" id="Loop-control" max="100" min="1" repeat="true"
template="instance('Loop-template')">
<xf:label mediatype="text/html" ref="$form-resources/Category1/Loop/label"/>
<xf:hint ref="$form-resources/Category1/Loop/hint"/>
<xf:alert ref="$form-resources/Category1/Loop/alert"/>
<xh:tr>
<xh:td>
<xf:select1 appearance="full" bind="Question-bind" id="Question-control">
<xf:label mediatype="text/html" ref="$form-resources/Category1/Loop/Question/label"/>
<xf:hint ref="$form-resources/Category1/Loop/Question/hint"/>
<xf:alert ref="$form-resources/Category1/Loop/Question/alert"/>
<xf:itemset ref="$form-resources/Category1/Loop/Question/item">
<xf:label ref="label"/>
<xf:value ref="value"/>
<xf:hint ref="hint"/>
</xf:itemset>
</xf:select1>
</xh:td>
</xh:tr>
</fr:section>
</fr:section>
</fr:body>
</fr:view>
</xh:body>
</xh:html>
在此示例中,对于Question的任何重复值,不可能有不同的值。
我真的需要为两个节点使用相同的名称,然后我认为使用完整的xpath是解决方案。因此问题是:我如何使用完整路径来处理可重复部分内的元素?对于任何其他情况,完整的xpath正常工作。 (此刻我正在使用Orbeon 4.7)。
答案 0 :(得分:1)
我首先应该说,在多个地方更改数据格式以支持相同的名称是一个麻烦。如果你这样做,将在表单生成器中中断,因为它目前是一个强有力的假设。 可能在Form Runner中也会中断。
这就是说,对于重复,你有来使用相对的XPath表达式。我没有看到解决方法。所以而不是:
<xf:bind id="Category1-bind" name="Category1" ref="/form/Category1">
<xf:bind id="Loop-bind" name="Loop" ref="/form/Category1/Loop">
<xf:bind id="Loop-iterator-bind" name="Loop-iterator"
ref="/form/Category1/Loop/Loop-iterator">
<xf:bind id="Question-bind" name="Question"
ref="/form/Category1/Loop/Loop-iterator/Question"
required="true()"/>
</xf:bind>
</xf:bind>
</xf:bind>
使用:
<xf:bind id="Category1-bind" name="Category1" ref="Category1">
<xf:bind id="Loop-bind" name="Loop" ref="Loop">
<xf:bind id="Loop-iterator-bind" name="Loop-iterator"
ref="Loop-iterator">
<xf:bind id="Question-bind" name="Question"
ref="Question"
required="true()"/>
</xf:bind>
</xf:bind>
</xf:bind>
它没有遵循这一点,通过在不同的地方使用相同的名称,您需要使用绝对路径。绑定可以用变量来引用,也可以是相对的。你应该有这样的层次结构:
<xf:bind id="section-personalData-bind" name="section-personalData">
<xf:bind id="age-bind" name="age" ref="age" required="true()"/>
</xf:bind>
<xf:bind id="section-kids-personalData-bind" name="section-kids-personalData">
<xf:bind id="section-kids-personalData-iteration-bind" name="section-kids-personalData-iterator">
<xf:bind id="age-1-bind" name="age-1" ref="age" required="true()"/>
</xf:bind>
</xf:bind>
参考$age
会找到第一个,提到$age-1
第二个。