如何在 XSLT3.0 中为以下代码启用流式传输,因为输入有效负载可能超过 80MB,并且我们正在观察性能问题

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

问题 当前的问题是,对于下面的 XSLT 代码,当输入有效负载很大(例如 80MB)时,输入有效负载将被加载到内存中,因此会消耗内存并导致性能问题。那么XSLT3.0中有没有办法处理这个问题呢?

如果我们使用 Streaming 可以解决问题吗?

<xsl:stylesheet version="3.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>
    
  
    <xsl:template match="/">
        <TOBRequest>
            
            <xsl:apply-templates select="TOBRequest/MessageHeader"/>
            <TOBRequest>
                <xsl:for-each select="TOBRequest/TOB">
                    <xsl:variable name="PEG" select="SAData/PEGroup"/>
                    
                    <!-- Apply templates, skipping few segments -->
                    <xsl:apply-templates select="@* | node()[not(name() = 'Item' or name() = 'CDE'/>

                    <xsl:for-each select="Item">
                        <Item>
                            <xsl:apply-templates select="@* | node()"/>
                            <xsl:variable name="ItemID" select="ID"/>
                            <xsl:variable name="Category" select="CategoryCode"/>
                            
                            <xsl:for-each select="../Item[HRelationship/ParentItemID = $ItemID]">
                                <xsl:choose>
                                    <xsl:when test="$Category = 'ABC' and not(contains($PEG, 'XYZ'))">
                                        <SubItem>
                                            <xsl:apply-templates select="@* | node()"/>
                                        </SubItem>
                                    </xsl:when>
                                    <xsl:when test="contains($PEG, 'XYZ')">
                                        <SubItem>
                                            <xsl:apply-templates select="@* | node()"/>
                                        </SubItem>
                                    </xsl:when>
                                </xsl:choose>
                            </xsl:for-each>
                        </Item>
                    </xsl:for-each>
                </xsl:for-each>
            </TransportationOrderBooking>
        </n0:TransportationOrderBookingRequest>
    </xsl:template>

    <!-- Template for copying elements -->
    <xsl:template match="*">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- Template for copying attributes -->
    <xsl:template match="@*">
        <xsl:copy/>
    </xsl:template>

</xsl:stylesheet>

xslt xslt-3.0
1个回答
0
投票

您的 XSLT 代码格式不正确,因此我很难验证。该代码无法按编写的方式进行流式传输,因为您多次访问

TOBRequest/TOB
的子代/后代 - 三个指令中的每一个指令

<xsl:variable name="PEG" select="SAData/PEGroup"/>
<xsl:apply-templates select="@* | node()[...]"/>
<xsl:for-each select="Item"> 

进行向下选择。还有一个问题是

<xsl:apply-templates select="TOBRequest/MessageHeader"/>

典型的解决方案是 (a) 如果 TOB 元素的大小是可管理的,则执行

<xsl:for-each select="copy-of(TOBRequest/TOB)">
以便将每个 TOB 构造为内存中的子树,并且每个 TOB 内的处理不会进行流式传输,并且 (b) 处理MessageHeader 元素与 TOB 元素在同一循环中,因此变为:

<xsl:for-each select="copy-of(TOBRequest/*)">
  <xsl:if test="self::MessageHeader">...</xsl:if>

如果您提供有效的 XSLT 代码和样本文档,那么帮助您重写会更容易。

© www.soinside.com 2019 - 2024. All rights reserved.