问题 当前的问题是,对于下面的 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 代码格式不正确,因此我很难验证。该代码无法按编写的方式进行流式传输,因为您多次访问
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 代码和样本文档,那么帮助您重写会更容易。