XSLT根据最大子节点对父节点进行排序

问题描述:

我已经浏览了所有关于XSLT排序的现有文章,但仍然无法找出适合我的排序情况的决定。 我需要先排序子节点(降序),然后根据第一个(最大)子值对父节点(降序)进行排序。XSLT根据最大子节点对父节点进行排序

所以,我需要最终订单NAME3,1,名称,但我有名称1,名称3,名称2

请帮忙找一个解决方案。提前致谢!

输入XML:

<collection> 
<products> 
    <product> 
     <productCode>001</productCode> 
     <productName>Name1</productName> 
     <subProducts> 
      <subProduct> 
       <prices> 
        <price> 
         <totalPrice>264.28</totalPrice> 
        </price>      
       </prices> 
      </subProduct> 
      <subProduct> 
       <prices> 
        <price> 
         <totalPrice>264.28</totalPrice> 
        </price> 
       </prices> 
      </subProduct>        
     </subProducts> 
    </product> 
    <product> 
     <productCode>002</productCode> 
     <productName>Name2</productName> 
     <subProducts> 
      <subProduct> 
       <prices> 
        <price> 
         <totalPrice>231.99</totalPrice> 
        </price> 
        <price> 
         <totalPrice>231.99</totalPrice> 
        </price> 
       </prices> 
      </subProduct> 
      <subProduct> 
       <prices> 
        <price> 
         <totalPrice>231.99</totalPrice> 
        </price> 
        <price> 
         <totalPrice>231.99</totalPrice> 
        </price> 
       </prices> 
      </subProduct>       
     </subProducts> 
    </product> 
    <product> 
     <productCode>003</productCode> 
     <productName>Name3</productName> 
     <subProducts> 
      <subProduct> 
       <prices> 
        <price> 
         <totalPrice>234.92</totalPrice> 
        </price> 
       </prices> 
      </subProduct> 
      <subProduct> 
       <prices> 
        <price> 
         <totalPrice>734.12</totalPrice> 
        </price>      
       </prices> 
      </subProduct>       
     </subProducts> 
    </product>   
</products> 
</collection> 

输出XML:(预期)

<products> 
<product> 
    <productName>Name3</productName> 
    <price>734.12</price> 
    <price>234.92</price> 
</product> 
<product> 
    <productName>Name1</productName> 
    <price>264.28</price> 
    <price>264.28</price> 
</product> 
<product> 
    <productName>Name2</productName> 
    <price>231.99</price> 
    <price>231.99</price> 
    <price>231.99</price> 
    <price>231.99</price> 
</product> 
</products> 

XSLT转换:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="/"> 
    <xsl:copy> 
     <xsl:apply-templates select="/collection/products/product"> 
      <xsl:sort select="subProducts/subProduct[1]/prices/price[1]/totalPrice" data-type="number" order="descending"/>    
     </xsl:apply-templates>   
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/collection/products/product">  
    <xsl:copy>   
     <productName> 
      <xsl:value-of select="productName"/> 
     </productName>   
     <xsl:apply-templates select="subProducts/subProduct/prices/price"> 
      <xsl:sort select="totalPrice" order="descending" data-type="number"/> 
     </xsl:apply-templates>   
    </xsl:copy> 
</xsl:template> 

<xsl:template match="subProducts/subProduct/prices/price"> 
    <xsl:copy> 
     <xsl:value-of select="totalPrice"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

错误XML输出:

<products> 
<product> 
    <productName>Name1</productName> 
    <price>264.28</price> 
    <price>264.28</price> 
</product> 
<product> 
    <productName>Name3</productName> 
    <price>734.12</price> 
    <price>234.92</price> 
</product> 
<product> 
    <productName>Name2</productName> 
    <price>231.99</price> 
    <price>231.99</price> 
    <price>231.99</price> 
    <price>231.99</price> 
</product> 
</products> 
+0

您将使用哪种XSLT处理器?在纯粹的XSLT 1.0中,没有扩展支持,你必须在两遍中完成。 –

+0

@ michael.hor257k我有机会使用Xalan – MsPineapple

如果您正在使用Xalan的处理器,你可以采取EXSLT math:max() extension function:

XSLT的优点1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:math="http://exslt.org/math" 
extension-element-prefixes="math"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/"> 
    <products> 
     <xsl:apply-templates select="collection/products/product"> 
      <xsl:sort select="math:max(subProducts/subProduct/prices/price/totalPrice)" data-type="number" order="descending"/>    
     </xsl:apply-templates>   
    </products> 
</xsl:template> 

<xsl:template match="product">  
    <xsl:copy>   
     <xsl:copy-of select="productName"/> 
     <xsl:apply-templates select="subProducts/subProduct/prices/price"> 
      <xsl:sort select="totalPrice" data-type="number" order="descending"/> 
     </xsl:apply-templates>   
    </xsl:copy> 
</xsl:template> 

<xsl:template match="price"> 
    <xsl:copy> 
     <xsl:value-of select="totalPrice"/> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

演示:http://xsltransform.net/3Mvmrzh/1

+0

非常感谢您的帮助!我已经在我的代码中成功测试过了。 – MsPineapple