首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XSLT基于元素和属性对重复项进行排序和删除

XSLT基于元素和属性对重复项进行排序和删除
EN

Stack Overflow用户
提问于 2014-07-11 15:44:07
回答 1查看 686关注 0票数 0

你能帮我解决我的XSLT问题吗?

offer/customer-attributes/custom-attribute/Feed_SKU要求:在我的XML中,提供/sku中的任何都是相等的,并且是比较普通的,那么我必须保留该记录(这意味着这是最新的记录,而忽略了另一条记录)。

我的案例Feed_SKU = 09/07/2014 23:21:20是最新的记录。

我尝试过xsl:key比较,并且有一些很难解析属性值(Feed_SKU)的时间。你能帮帮我吗。

输入XML:

代码语言:javascript
复制
<?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> 

我的工作是:(不工作)

代码语言:javascript
复制
  <?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>
EN

回答 1

Stack Overflow用户

发布于 2014-07-11 18:32:51

这个问题有两个部分,一是将共享相同sku的报价分组在一起,二是在每个组中查找最新的日期。对于第一部分,您可以使用Muenchian分组,第二部分您需要创造性地处理字符串操作-XSLT1.0没有对日期和时间的任何特殊支持,因此您需要将时间戳值按摩到一个按时间顺序排序与字典顺序匹配的表单中。

代码语言:javascript
复制
<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调用才能获得正确的订单。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24701609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档