提问人:Roberto 提问时间:12/18/2017 最后编辑:Roberto 更新时间:12/23/2017 访问量:221
Orbeon - 极慢的xml大数据导入[加载并保存]
Orbeon - Extremely slow xml big data import [load and save]
问:
我正在创建一个具有 xml 文件导入功能的表单。我想迭代导入的 xml 文件以获取网格表的相应行。 每一行都由一组不同的输入文本组成(例如,每行有十个输入文本组件),这些文本是使用导入的 xml 文件中的相应值以二元方式创建的。
xml 文件的结构如下:
<nodeList>
<node>
<value1>test</value1>
<value2>test</value2>
<value3>test</value3>
<value4>test</value4>
<value5>test</value5>
<value6>test</value6>
<value7>test</value7>
<value8>test</value8>
<value9>test</value9>
<value10>test</value10>
</node>
...
(with N nodes)
</nodeList>
因此,我的任务是通过这 N 个节点创建 N 行。
首先,我使用 xforms 上传组件和一个带有 iterate 属性的操作来实现此任务,以遍历在单独实例中加载的 xml 文件节点:每次迭代在重复网格中插入一行(带有模板),然后执行一组 setvalue 以将值加载到每行的每个输入文本组件中。逻辑如下:
<xf:instance id="upload">
<serialized mediatype="application/xml" filename=""/>
</xf:instance>
<xf:bind ref="instance('upload')" type="xs:base64Binary"/>
<xf:submission id="upload-submission" ref="instance('upload')" validate="false"
relevant="false"
method="post"
replace="none"
resource="echo:"/>
<xf:action id="upload-binding">
<!-- Request actions -->
<xf:action event="xforms-submit" ev:observer="upload-submission">
<!-- Copy over to read-write request instance -->
<xf:insert ref="instance('fr-service-response-instance')"
origin="saxon:parse(saxon:base64Binary-to-string(xs:base64Binary(instance('upload')), 'UTF-8'))"/>
</xf:action>
<xf:action event="xforms-submit-done" ev:observer="upload-submission">
<xf:delete ref="instance('fr-form-instance')//nodes-iteration"/>
<xf:action iterate="instance('fr-service-response-instance')//*:node">
<xf:insert context="instance('fr-form-instance')//nodes" ref="*"
origin="instance('nodes-template')"/>
<xf:setvalue ref="instance('fr-form-instance')//nodes-iteration[last()]/value1"
value="context()//*:value1"/>
<xf:setvalue ref="instance('fr-form-instance')//nodes-iteration[last()]/value2"
value="context()//*:value2"/>
<xf:setvalue ref="instance('fr-form-instance')//nodes-iteration[last()]/value3"
value="context()//*:value3"/>
...
(with N xf:setvalue)
</xf:action>
</xf:action>
</xf:action>
.......
<xf:upload id="upload-div" ref="instance('upload')">
<xf:filename ref="@filename"/>
<xf:mediatype ref="@mediatype"/>
<xf:send event="xxforms-upload-done" submission="upload-submission"/>
</xf:upload>
这个解决方案很好,但速度很慢,所以我尝试使用 xforms repeat 组件并将整个 xml 文件节点直接插入到与 repeat 组件关联的实例中。
相反,这个解决方案更快,但对于 5000 个节点,我们的表单加载组件也非常慢(1 分 42 秒)。
对于 5000 个节点,只有保存操作需要 7 分 45 秒才能完成。
保存了这 5000 个节点的表单的加载页面需要花费 2 分 26 秒才能完成。
我需要减少这些时间。 我还尝试使用不同的环境(使用更好的硬件)或配置(我也尝试禁用验证系统),但时间几乎相同。
已编辑以获取更多信息:
我将代码恢复到这个旧解决方案并尝试一下:单个插入有效,但不能。
我应该只替换索引吗?setvalue set
last()
current()
setvalue ref
<xf:setvalue ref="instance('fr-form-instance')//nodes-iteration[current()]/value1" value="context()//*:value1"/>
如果是这样,它仍然不起作用,并且需要花费太多时间才能完成。
相反,您对组件有一些建议吗?这是我们的最后一个解决方案:xf:repeat
<xf:bind ref="instance('fr-form-instance')/nodes-iteration//*:node">
<xf:bind id="value1-bind" ref="./*:value1" required="true()"/>
<xf:bind id="value2-bind" ref="./*:value2" required="true()"/>
<xf:bind id="value3-bind" ref="./*:value3" type="xs:date" required="true()"/>
<xf:bind id="value4-bind" ref="./*:value4" required="true()"/>
<xf:bind id="value5-bind" ref="./*:value5" />
<xf:bind id="value6-bind" ref="./*:value6" required="true()"/>
<xf:bind id="value7-bind" ref="./*:value7" required="true()"/>
<xf:bind id="value8-bind" ref="./*:value8" required="true()"/>
<xf:bind id="value9-bind" ref="./*:value9" required="true()"/>
<xf:bind id="value10-bind" ref="./*:value10" required="true()"/>
</xf:bind>
...
<xf:instance id="node-item" >
<data>
<node>
<value1/>
<value2/>
<value3/>
<value4/>
<value5/>
<value6/>
<value7/>
<value8/>
<value9/>
<value10/>
</node>
</data>
</xf:instance>
<xf:instance id="upload" >
<serialized mediatype="application/xml" filename=""/>
</xf:instance>
<xf:bind ref="instance('upload')" type="xs:base64Binary"/>
<xf:submission id="upload-submission" ref="instance('upload')" validate="false"
relevant="false"
method="post"
replace="none"
resource="echo:"/>
<!-- Request actions -->
<xf:action event="xforms-submit-done" ev:observer="upload-submission">
<!-- Copy over to read-write request instance -->
<xf:insert ref="instance('fr-form-instance')/nodes-iteration/data"
origin="saxon:parse(saxon:base64Binary-to-string(xs:base64Binary(instance('upload')), 'UTF-8'))"/>
</xf:action>
...
<fr:section id="nodes-iteration-control" bind="nodes-iteration-bind">
<xf:label ref="$form-resources/nodes-iteration/label"/>
<xh:table class="fr-grid fr-grid-4 fr-grid-nodes table table-bordered table-condensed fr-repeat fr-repeat-multiple-rows">
<xh:thead class="fr-grid-head">
<xh:tr class="fr-grid-tr">
<xh:th class="fr-grid-th xforms-table-header">
<xf:trigger id="addNew-control" bind="addNew-bind">
<xf:label>Aggiungi Nuovo</xf:label>
<xf:action event="DOMActivate">
<xf:insert ref="instance('fr-form-instance')//*:node" at="last()" position="after" origin="instance('node-item')//*:node"/>
</xf:action>
<xf:hint ref="$form-resources/addNew/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:trigger>
</xh:th>
</xh:tr>
</xh:thead>
<xh:tbody class="fr-grid-body">
<xf:repeat id="node-repeats" ref="instance('fr-form-instance')/nodes-iteration//*:node" >
<xh:tr class="fr-grid-tr can-insert-above can-insert-below xforms-repeat-selected-item-1">
<xh:td class="fr-grid-td">
<xf:var name="countRow" value="position()"/>
<xf:trigger id="removeItem-control" bind="removeItem-bind">
<xf:label>X</xf:label>
<xf:action event="DOMActivate" if="$countRow = 1">
<xf:setvalue ref="instance('fr-form-instance')/nodes-iteration//*:node[$countRow]/*:value1" value="''"/>
<xf:setvalue ref="instance('fr-form-instance')/nodes-iteration//*:node[$countRow]/*:value2" value="''"/>
<xf:setvalue ref="instance('fr-form-instance')/nodes-iteration//*:node[$countRow]/*:value3" value="''"/>
<xf:setvalue ref="instance('fr-form-instance')/nodes-iteration//*:node[$countRow]/*:value4" value="''"/>
<xf:setvalue ref="instance('fr-form-instance')/nodes-iteration//*:node[$countRow]/*:value5" value="''"/>
<xf:setvalue ref="instance('fr-form-instance')/nodes-iteration//*:node[$countRow]/*:value6" value="''"/>
<xf:setvalue ref="instance('fr-form-instance')/nodes-iteration//*:node[$countRow]/*:value7" value="''"/>
<xf:setvalue ref="instance('fr-form-instance')/nodes-iteration//*:node[$countRow]/*:value8" value="''"/>
<xf:setvalue ref="instance('fr-form-instance')/nodes-iteration//*:node[$countRow]/*:value9" value="''"/>
<xf:setvalue ref="instance('fr-form-instance')/nodes-iteration//*:node[$countRow]/*:value10" value="''"/>
</xf:action>
<xf:action event="DOMActivate" if="$countRow != 1">
<xf:delete ref="instance('fr-form-instance')/nodes-iteration//*:node" at="index('node-repeats')"/>
</xf:action>
<xf:hint ref="$form-resources/removeItem/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:trigger>
<xf:input id="nodeNumber-control" ref="$countRow">
<xf:label ref="$form-resources/nodeNumber/label"/>
<xf:hint ref="$form-resources/nodeNumber/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</xh:td>
<xh:td class="fr-grid-td">
<xf:input id="value1-control" bind="value1-bind">
<xf:label ref="$form-resources/value1/label"/>
<xf:hint ref="$form-resources/value1/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</xh:td>
<xh:td class="fr-grid-td">
<xf:input id="value2-control" bind="value2-bind">
<xf:label ref="$form-resources/value2/label"/>
<xf:hint ref="$form-resources/value2/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</xh:td>
<xh:td class="fr-grid-td">
<xf:input id="value3-control" bind="value3-bind">
<xf:label ref="$form-resources/value3/label"/>
<xf:hint ref="$form-resources/value3/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</xh:td>
</xh:tr>
<xh:tr class="fr-grid-tr xforms-repeat-selected-item-1">
<xh:td class="fr-grid-td">
<xf:input id="value4-control" bind="value4-bind">
<xf:label ref="$form-resources/value4/label"/>
<xf:hint ref="$form-resources/value4/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</xh:td>
<xh:td class="fr-grid-td">
<xf:input id="value5-control" bind="value5-bind">
<xf:label ref="$form-resources/value5/label"/>
<xf:hint ref="$form-resources/value5/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</xh:td>
<xh:td class="fr-grid-td" style="border-bottom: 1px solid #ddd;">
<xf:input id="value6-control" bind="value6-bind">
<xf:label ref="$form-resources/value6/label"/>
<xf:hint ref="$form-resources/value6/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</xh:td>
<xh:td class="fr-grid-td" style="border-bottom: 1px solid #ddd;">
<xf:input id="value7-control" bind="value7-bind">
<xf:label ref="$form-resources/value7/label"/>
<xf:hint ref="$form-resources/value7/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</xh:td>
</xh:tr>
<xh:tr class="fr-grid-tr xforms-repeat-selected-item-1">
<xh:td class="fr-grid-td">
<xf:input id="value8-control" bind="value8-bind">
<xf:label ref="$form-resources/value8/label"/>
<xf:hint ref="$form-resources/value8/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</xh:td>
<xh:td class="fr-grid-td">
<xf:input id="value9-control" bind="value9-bind">
<xf:label ref="$form-resources/value9/label"/>
<xf:hint ref="$form-resources/value9/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</xh:td>
<xh:td class="fr-grid-td">
<xf:input id="value10-control" bind="value10-bind">
<xf:label ref="$form-resources/value10/label"/>
<xf:hint ref="$form-resources/value10/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</xh:td>
</xh:tr>
</xf:repeat>
</xh:tbody>
</xh:table>
</fr:section>
谢谢
罗伯托
答:
我怀疑对性能的最大影响来自运行 .所以我建议你试着把它移到你的循环之外,这只有 1 .因此,在 之后,您将执行:<xf:insert>
<xf:insert>
<xf:delete>
<xf:insert
context="instance('fr-form-instance')//nodes"
ref="*"
origin="
for $i in (1 to count(instance('fr-service-response-instance')//*:node))
return instance('nodes-template')"/>
然后在 中,您将删除对 的调用,并且需要更改 以定位“当前”,而不是最后一个,内容如下:<xf:action iterate="…">
<xf:insert>
<xf:setvalue>
nodes-iteration
<xf:action iterate="instance('fr-service-response-instance')//*:node">
<xf:var name="i" value="count(preceding-sibling::*) + 1"/>
<xf:setvalue ref="instance('fr-form-instance')//nodes-iteration[$i]/value1"
value="context()//*:value1"/>
<xf:setvalue ref="instance('fr-form-instance')//nodes-iteration[$i]/value2"
value="context()//*:value2"/>
<xf:setvalue ref="instance('fr-form-instance')//nodes-iteration[$i]/value3"
value="context()//*:value3"/>
</xf:action>
评论
[last()]
[last()]
[context()]
xf:insert
评论