Orbeon - 非常慢的xml大数据导入[加载并保存]

问题描述 投票:0回答:1

我正在创建一个带有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>

谢谢

罗伯托

xml xpath xhtml orbeon xforms
1个回答
0
投票

我怀疑性能最大的打击来自运行<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>
© www.soinside.com 2019 - 2024. All rights reserved.