使用XSLT 1.0对分组的项目进行排序

时间:2017-01-06 14:46:18

标签: xslt xslt-1.0

我有一个相当大的XML文件,其中包含车辆型号列表,价格和每月付款价格。其中有很多其他信息,但那些是我感兴趣的数据的重要部分。

那里有不同价格/每月付款的重复模型。到目前为止,我在这个论坛的帮助下完成的任务是构建一个独特的模型列表(IE。没有重复项),显示该模型中价格最低的车辆。

我坚持下去,我是否需要对此列表进行排序,将每月最低付款显示为每月最高付款。复杂性是最低价格的车辆并不总是等于最低的每月付款。

我的XML看起来有点像这样:

add_action( 'woocommerce_after_single_product_summary', 'custom_single_product_banner', 12 );
function custom_single_product_banner() {

    $output = '<div class="product-footer">
        <h1 class="product-footer-text">Need some additional help? Or have an enquiry?</h1>
        <h5 class="product-footer-text"><i class="fa fa-phone"></i>  Call one of our sales team on <strong>01782</strong></h5>
        <h5 class="product-footer-text" style="margin-top: -40px;"><i class="fa fa-envelope"></i>  Contact us via our contact page <strong><a style="color: #ffffff;" href="/../contact" target="_blank">HERE</a></strong></h5>
        <p class="product-footer-text"><i><strong>Order note: </strong>All prices above are subject to delivery charges and VAT where applicable </i></span></p>
    </div>';
    echo $output;
}

正如我所说,其中有大量其他数据,但这是基本结构。

我的XSLT看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<Dealer>
    <Vehicle>
        <Model>KA</Model>
        <DealerPriceNoFormat>8700.00</DealerPriceNoFormat>
        <OptionsFinanceMonthlyPayment>300.50</OptionsFinanceMonthlyPayment>
    </Vehicle>
    <Vehicle>
        <Model>KA</Model>
        <DealerPriceNoFormat>10000.50</DealerPriceNoFormat>
        <OptionsFinanceMonthlyPayment>270.50</OptionsFinanceMonthlyPayment>
    </Vehicle>
    <Vehicle>
        <Model>Focus</Model>
        <DealerPriceNoFormat>12000.00</DealerPriceNoFormat>
        <OptionsFinanceMonthlyPayment>340.00</OptionsFinanceMonthlyPayment>
    </Vehicle>
    <Vehicle>
        <Model>KA</Model>
        <DealerPriceNoFormat>9910.00</DealerPriceNoFormat>
        <OptionsFinanceMonthlyPayment>430.75</OptionsFinanceMonthlyPayment>
    </Vehicle>
    <Vehicle>
        <Model>KUGA</Model>
        <DealerPriceNoFormat>23010.00</DealerPriceNoFormat>
        <OptionsFinanceMonthlyPayment>550.20</OptionsFinanceMonthlyPayment>
    </Vehicle>
    <Vehicle>
        <Model>Focus</Model>
        <DealerPriceNoFormat>15900.00</DealerPriceNoFormat>
        <OptionsFinanceMonthlyPayment>430.00</OptionsFinanceMonthlyPayment>
    </Vehicle>
</Dealer>

就像我说的那样,我几乎就在那里,只是无法弄清楚如何通过OptionsFinanceMonthlyPayment对输出列表进行排序。

所以在上面的情况下输出看起来像这样,显示每个型号中最便宜的车,但按输出列表上的每月付款排序:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="html" omit-xml-declaration="yes" indent="yes" version="4.0" encoding="iso-8859-1" />
  <xsl:key name="by-id" match="Dealer/Vehicle" use="Model"/>
  <xsl:template match="Dealer">
    <xsl:copy>
      <xsl:for-each select="Vehicle[generate-id() = generate-id(key('by-id', Model)[1])]">
        <xsl:for-each select="key('by-id', Model)">
          <xsl:sort select="DealerPriceNoFormat" data-type="number" order="ascending" />
          <xsl:if test="position()=1">
            <p> 
                <xsl:value-of select="Model" /><br />
                <xsl:value-of select="DealerPriceNoFormat" /><br />
                <xsl:value-of select="OptionsFinanceMonthlyPayment" /> 
            </p>
          </xsl:if>
        </xsl:for-each>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

提前致谢。

1 个答案:

答案 0 :(得分:2)

我会在两次传球中做到这一点 - 比如:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">

<xsl:key name="vehicle-by-model" match="Vehicle" use="Model"/>

<xsl:template match="/Dealer">
    <!-- first-pass -->
    <xsl:variable name="groups">
        <xsl:for-each select="Vehicle[generate-id() = generate-id(key('vehicle-by-model', Model)[1])]">
            <group>
                <xsl:for-each select="key('vehicle-by-model', Model)">
                    <xsl:sort select="DealerPriceNoFormat" data-type="number" order="ascending" />
                    <xsl:if test="position()=1">
                        <model><xsl:value-of select="Model" /></model>
                        <price><xsl:value-of select="DealerPriceNoFormat" /></price>
                        <pmt><xsl:value-of select="OptionsFinanceMonthlyPayment" /></pmt>
                    </xsl:if>
                </xsl:for-each>
            </group>
        </xsl:for-each>
    </xsl:variable>
    <!-- output -->
    <html>
        <xsl:for-each select="exsl:node-set($groups)/group">
            <xsl:sort select="pmt" data-type="number" order="ascending" />
            <p> 
                <xsl:value-of select="model" /><br />
                <xsl:value-of select="price" /><br />
                <xsl:value-of select="pmt" /> 
            </p>
        </xsl:for-each>
    </html>
</xsl:template>

</xsl:stylesheet>

请注意,这需要一个支持node-set()扩展功能的处理器。