请你帮我解决我被击中的XSLT,
要求:在我的XML记录中,任何offer / sku都是相同的,并且offer / customer-attributes / custom-attribute / Feed_SKU更重要,那么我必须保留该记录(这意味着这是最新的记录并忽略另一个)。
我的案例Feed_SKU = 09/07/2014 23:21:20是最新记录。
我尝试过使用xsl:key compare并且很难解析属性值(Feed_SKU)。你能帮帮我吗?
输入XML:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<enfinity xmlns="http://www.intershop.com/xml/ns/enfinity/6.5/xcs/impex" xsi:schemaLocation="http://www.intershop.com/xml/ns/enfinity/6.5/xcs/impex catalog.xsd http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt dt.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" family="enfinity" major="6" minor="1">
<offer import-mode="UPDATE" sku="36-5149574">
<sku>36-5149574</sku>
<custom-attributes>
<custom-attribute name="OriginalFileName" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">Message_20140709_2321130190_BP71794596.dat_SKU</custom-attribute>
<custom-attribute name="FacilityId" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">385</custom-attribute>
<custom-attribute name="GII" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">6661116</custom-attribute>
<custom-attribute name="CountryOrigin" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">US</custom-attribute>
<custom-attribute name="UOMSystem" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">I</custom-attribute>
<custom-attribute name="CartonType" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">AF</custom-attribute>
<custom-attribute name="Catalog" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">36</custom-attribute>
<custom-attribute name="Height" dt:dt="quantity" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">3 in</custom-attribute>
<custom-attribute name="Length" dt:dt="quantity" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">14 in</custom-attribute>
<custom-attribute name="Width" dt:dt="quantity" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">10.5 in</custom-attribute>
<custom-attribute name="Weight" dt:dt="quantity" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">9.7 lb</custom-attribute>
<custom-attribute name="Feed_SKU" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">09/07/2014 23:21:14</custom-attribute>
</custom-attributes>
</offer>
<offer import-mode="UPDATE" sku="36-5149574">
<sku>36-5149574</sku>
<custom-attributes>
<custom-attribute name="OriginalFileName" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">Message_20140709_2321130190_BP71794596.dat_SKU</custom-attribute>
<custom-attribute name="FacilityId" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">385</custom-attribute>
<custom-attribute name="GII" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">6661116</custom-attribute>
<custom-attribute name="CountryOrigin" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">US</custom-attribute>
<custom-attribute name="UOMSystem" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">I</custom-attribute>
<custom-attribute name="CartonType" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">AF</custom-attribute>
<custom-attribute name="Catalog" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">36</custom-attribute>
<custom-attribute name="Height" dt:dt="quantity" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">3 in</custom-attribute>
<custom-attribute name="Length" dt:dt="quantity" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">14 in</custom-attribute>
<custom-attribute name="Width" dt:dt="quantity" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">10.5 in</custom-attribute>
<custom-attribute name="Weight" dt:dt="quantity" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">9.7 lb</custom-attribute>
<custom-attribute name="Feed_SKU" dt:dt="string" xmlns:dt="http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt">09/07/2014 23:23:23</custom-attribute>
</custom-attributes>
</offer>
</enfinity>
XLST我正在努力:(不工作)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:impex="http://www.intershop.com/xml/ns/enfinity/6.5/xcs/impex"
xsi:schemaLocation="http://www.intershop.com/xml/ns/enfinity/6.5/xcs/impex catalog.xsd http://www.intershop.com/xml/ns/enfinity/6.5/core/impex-dt dt.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output omit-xml-declaration="no" indent="yes" method="xml"/>
<!-- key for grouping -->
<xsl:key name="offerBySku" match="impex:offer" use="impex:sku"/>
<xsl:template match="/*">
<xsl:copy>
<!-- transfer attributes of the document element -->
<xsl:copy-of select="@*"/>
<!-- Muenchian method to get one iteration per sku -->
<xsl:for-each select="impex:offer[generate-id() = generate-id(key('offerBySku', impex:sku)[1])]">
<!-- sort the group by descending timestamp -->
<xsl:for-each select="key('offerBySku', impex:sku)">
<!-- rearrange the timestamp to year, month, day, time -->
<xsl:sort order="descending" select="concat(
substring(impex:custom-attributes/impex:custom-attribute[@name='Feed_SKU'], 7, 4),
substring(impex:custom-attributes/impex:custom-attribute[@name='Feed_SKU'], 4, 2),
substring(impex:custom-attributes/impex:custom-attribute[@name='Feed_SKU'], 1, 2),
substring(impex:custom-attributes/impex:custom-attribute[@name='Feed_SKU'], 11))"/>
<!-- copy just the first element in sorted order, i.e. the one with the latest date-->
<xsl:copy-of select="."/>
<xsl:if test="position() = 1">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:1)
此问题分为两部分,首先将共享相同sku
的商品组合在一起,然后在每个组中查找最新日期。对于第一部分,您可以使用Muenchian分组,对于第二部分,您需要通过字符串操作获得创造性 - XSLT 1.0对日期和时间没有任何特殊支持,因此您需要将时间戳值按摩到按时间顺序匹配的形式词典排序。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:impex="http://www.intershop.com/xml/ns/enfinity/6.5/xcs/impex">
<!-- key for grouping -->
<xsl:key name="offerBySku" match="impex:offer" use="impex:sku" />
<xsl:template match="/*">
<xsl:copy>
<!-- transfer attributes of the document element -->
<xsl:copy-of select="@*"/>
<!-- Muenchian method to get one iteration per sku -->
<xsl:for-each select="impex:offer[
generate-id() = generate-id(key('offerBySku', impex:sku)[1])]">
<!-- sort the group by descending timestamp -->
<xsl:for-each select="key('offerBySku', impex:sku)">
<!-- rearrange the timestamp to year, month, day, time -->
<xsl:sort order="descending" select="concat(
substring(impex:custom-attributes/impex:custom-attribute[
@name='Feed_SKU'], 7, 4),
substring(impex:custom-attributes/impex:custom-attribute[
@name='Feed_SKU'], 4, 2),
substring(impex:custom-attributes/impex:custom-attribute[
@name='Feed_SKU'], 1, 2),
substring(impex:custom-attributes/impex:custom-attribute[
@name='Feed_SKU'], 11))" />
<!-- copy just the first element in sorted order, i.e. the one with
the latest date -->
<xsl:if test="position() = 1">
<xsl:copy-of select="." />
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:copy>
</xsl:template>
我假设时间戳是dd / mm / yyyy,因为2014年9月7日将在问这个问题的日期之后,但如果它们实际上是mm / dd / yyyy那么你将不得不交换第二次和第三次substring
调用以获得正确的排序。