Использование для каждой группы с условием в группе - PullRequest
0 голосов
/ 06 сентября 2018

Я хочу сгруппировать элементы по id, используя for-each-group, и группировать только в том случае, если они находятся в другом источнике, если источником является та же самая группа, даже если у нее одинаковый идентификатор

<items>
    <item id="123" source="loc1">
        <price>12</price>
        <description>test</description> 
    </item>

    <item id="123" source="loc2">
        <price>122</price>
        <description>test</description> 
    </item>

    <item id="234" source="loc1">
        <price>566</price>
        <description>test</description> 
    </item>

    <item id="456" source="loc2">
        <price>222</price>
        <description>desc</description> 
    </item>

    <item id="456" source="loc2">
        <price>312</price>
        <description>desc</description> 
    </item>

    <item id="768" source="loc1">
        <price>212</price>
        <description>desc</description> 
    </item>

    <item id="768" source="loc2">
        <price>934</price>
        <description>desc</description> 
    </item>
  </items>

И вот так будет

<items>
    <group>
         <item id="123" source="loc1">
            <price>12</price>
            <description>test</description> 
         </item>

         <item id="123" source="loc2">
            <price>122</price>
            <description>test</description> 
         </item>
    </group>

    <group>
        <item id="234" source="loc1">
           <price>566</price>
           <description>test</description> 
        </item>
    </group>

    <group>
        <item id="456" source="loc2">
           <price>222</price>
           <description>desc</description> 
        </item>
    </group>

     <group>
        <item id="456" source="loc2">
           <price>222</price>
           <description>desc</description> 
        </item>
    </group>

    <group>
       <item id="768" source="loc1">
          <price>212</price>
          <description>desc</description> 
       </item>

       <item id="768" source="loc2">
           <price>934</price>
           <description>desc</description> 
       </item>
    </group>
</items>

Обновление

Группировать по идентификатору

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="items">
    <xsl:copy>
        <xsl:for-each-group select="item" group-by="@id">
            <group>
                <xsl:apply-templates select="current-group()"/>
            </group>
        </xsl:for-each-group>

    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

1 Ответ

0 голосов
/ 07 сентября 2018

Я думаю, что ваше требование может быть реализовано с помощью group-by="@id", а затем внутри, с помощью чека count(distinct-values(current-group()/@source)) = count(current-group()), чтобы решить, следует ли обернуть все элементы в current-group() в одну обертку элемента group или обернуть каждый элемент своего собственного:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="xml" indent="yes"/>


  <xsl:template match="items">
      <xsl:copy>
          <xsl:for-each-group select="item" group-by="@id">
              <xsl:choose>
                  <xsl:when test="count(distinct-values(current-group()/@source)) = count(current-group())">
                      <group>
                          <xsl:apply-templates select="current-group()"/>
                      </group>
                  </xsl:when>
                  <xsl:otherwise>
                      <xsl:for-each select="current-group()">
                          <group>
                              <xsl:apply-templates select="."/>
                          </group>
                      </xsl:for-each>
                  </xsl:otherwise>
              </xsl:choose>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Онлайн пример на https://xsltfiddle.liberty -development.net / pPqsHTR , не то чтобы я исправил два последних элемента item во входной выборке, чтобы иметь атрибут source вместо name они есть в вашем посте.

...