2015-05-29 75 views
0

我有父级和子级标记结构,需要迭代父级标记的子级并以新格式设置值。xslt处理时的性能问题

属性可以针对父标签和子标签重复使用。

我们需要检查值/标签是否存在于孩子中,然后将其从父母标签中取出。

下面是示例XML

<?xml version="1.0" encoding="UTF-8"?> 
<item> 
    <perishable-indicator >N</perishable-indicator> 
    <product-shelf-security-type >ST - SMALL TOY</product-shelf-security-type> 
    <before-date>2012-05-30</before-date> 
    <partnumber>2</partnumber> 
    <season>BASIC SEASON</season> 
    <variant> 
    <partnumber>4</partnumber> 
    <season>BASIC SEASON</season> 
    <division-code>055</division-code> 
    <department-code>013</department-code> 
    <class-code>089</class-code> 
    </variant> 
</item> 

,这里是样品XSLT我使用迭代双方家长和孩子:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> 
<xsl:template match="item"> 
<Product> 
    <xsl:variable name="productperishable" select="perishable-indicator"/> 
    <xsl:variable name="productsecurity-type" select="product-shelf-security-type"/> 
    <xsl:variable name="productbefore-date" select="before-date"/> 
    <xsl:variable name="productpartnumber" select="partnumber"/> 
    <xsl:variable name="productseason" select="season"/> 
<xsl:for-each select="variant"> 
<sku> 
<xsl:choose> 
<xsl:when test="partnumber"> 
<PartNumber><xsl:value-of select="partnumber"/></PartNumber> 
</xsl:when> 
<xsl:when test="$productpartnumber!=''">      
<PartNumber><xsl:value-of select="$productpartnumber"/></PartNumber>      
</xsl:when> 
</xsl:choose> 
<xsl:choose> 
<xsl:when test="perishable-indicator"> 
<PartNumber><xsl:value-of select="perishable-indicator"/></PartNumber> 
</xsl:when> 
<xsl:when test="$productperishable!=''">      
<Perishable><xsl:value-of select="$productperishable"/></Perishable>      
</xsl:when> 
</xsl:choose> 
</sku> 
</xsl:for-each> 
</Product> 
</xsl:template> 
</xsl:stylesheet> 

但是,如果我们需要遍历多个项目并按变种目前输入xml,转换过程需要很长时间。任何输入都会有很大的帮助。

+0

能否请您解释一下您的XSLT在这里做?我只能在'partnumber'和'perishable-indicator'上看到'when'条件。它只是关于这两个元素吗? –

+0

这仅仅是两个元素的一个例子,我们对父代和子代标签都有近40-50个元素。 – Rajeev

+0

你说你必须迭代几个'items' ..我可以在你的XML中只看到1个'item'(根元素)。你能描述一下实时场景吗? –

回答

0

所示的编码技术将执行很长时间,因为XSLT引擎被迫使用编码循环,而不是使用内置的渲染引擎,并且许多值首先被复制到变量而不是立即复制到输出流。

请注意,使用其他编码技术时,xslt渲染引擎将自动循环所有元素。将XSLT看作是渲染引擎的规范而不是编程语言。在这种编码技术中,<xsl:apply-templates>(而不是<xsl:for-each>)告诉呈现引擎继续使用它在实际上下文中遇到的任何XML标记。

默认XSLT模板创建输入的精确副本:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml"/> 

    <xsl:template match="/"> 
     <xsl:apply-templates /> 
    </xsl:template> 

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

</xsl:stylesheet> 

正如你可以看到有这个样式表没有<xsl:for-each>命令。您可以使用此规范创建编译的XSLT渲染,并检查运行时间的差异。

现在您可以添加转换模板。

如果我正确理解你的天赋,你想添加

<xsl:template match="item"> 
    <Product> 
     <xsl:apply-templates select="variant"/> 
    </Product> 
</xsl:template> 

<xsl:template match="variant"> 
    <sku> 
     <xsl:choose> 
     <xsl:when test="partnumber != ''"> 
      <xsl:apply-templates select="partnumber"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:apply-templates select="../partnumber"/> 
     </xsl:otherwise> 
     </xsl:choose> 
     <xsl:choose> 
     <xsl:when test="perishable-indicator!= ''"> 
      <xsl:apply-templates select="perishable-indicator"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:apply-templates select="../perishable-indicator"/> 
     </xsl:otherwise> 
     </xsl:choose> 
    </sku> 
</xsl:template> 

这应包括的基本知识。用这个规范编译一个xslt处理器,让我知道这是否比你当前的处理速度更快。

接下来要与你的输出规格完全相同兼容,你应该建立两个格式模板来重命名所生成的标记:

<xsl:template match="partnumber"> 
    <PartNumber> 
     <xsl:apply-templates/> 
    </PartNumber> 
</xsl:template> 

<xsl:template match="perishable-indicator"> 
    <Perishable> 
     <xsl:apply-templates/> 
    </Perishable> 
</xsl:template> 

这将创建输出

<document> 
    <Product> 
     <sku> 
     <PartNumber>4</PartNumber> 
     <Perishable>N</Perishable> 
     </sku> 
    </Product> 
</document>