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

Orbeon - Extremely slow xml big data import [load and save]

提问人:Roberto 提问时间:12/18/2017 最后编辑:Roberto 更新时间:12/23/2017 访问量:221

问:

我正在创建一个具有 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 setlast()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 XForeon XFores

评论


答:

0赞 avernet 12/19/2017 #1

我怀疑对性能的最大影响来自运行 .所以我建议你试着把它移到你的循环之外,这只有 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>

评论

0赞 Roberto 12/21/2017
嗨,亚历山德罗,我回答你。
0赞 avernet 12/21/2017
@Roberto Meta:你发布了我的答案的后续作为另一个答案,这不是 Stack Overflow 的工作方式。答案仅用于回答原始问题,而不是后续讨论。因此,我建议您删除该“答案”,并在下面的评论中发布摘要。
0赞 avernet 12/21/2017
@Roberto 就您而言,我建议的解决方案的性能是否更好,暂时忘记了如果您不断更新内部循环,它就不会做您想要的?如果它更好/可以接受,那么我们可以弄清楚如何解决这个问题(否则,我想尝试是没有意义的)。[last()]
0赞 Roberto 12/21/2017
不,在不更新循环内 [last()] 的情况下,性能会更好。相反,使用 [current()] 索引会更慢,并且它只在第一个节点上设置值。对不起,我的答案是错误的,我试图在这里发布该代码,但它太长了。
0赞 avernet 12/22/2017
@Roberto我不是想对比 vs. ,而是想知道它是否在循环外运行得更快。是吗?如果是这样,这在多大程度上提高了性能?[last()][context()]xf:insert