Orbeon - 非常慢的xml大数据导入[加载并保存]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Orbeon - 非常慢的xml大数据导入[加载并保存]相关的知识,希望对你有一定的参考价值。
我正在创建一个带有xml文件导入功能的表单。我想迭代导入的xml文件以获取网格表的相应行。每行由一组不同的输入文本组成(例如,每行有十个输入文本组件),这些文本是使用导入的xml文件中的相应值以dinamically方式创建的。
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>
谢谢
罗伯托
我怀疑性能最大的打击来自运行<xf:insert>
的成本。所以我建议你尝试将它移到你的循环之外,这只有1个<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>
以上是关于Orbeon - 非常慢的xml大数据导入[加载并保存]的主要内容,如果未能解决你的问题,请参考以下文章