2016-05-04 4 views
1

Я пытаюсь использовать групповые функции в XSLT 2.0 в XSLT 1.0. У меня есть код, работающий в XSLT 2.0, но мой процессор не обрабатывает xslt 2.0. Поэтому мне нужна помощь с помощью групповой функции в xslt 1.0.Как использовать групповые функции из XSLT 2.0 в XSLT 1.0?

XML данные:

   <table> 
       <row> 
        <month>03</month> 
        <year>2016</year> 
        <Id>10101</Id> 
        <Number>1</Number> 
        <code>A2004</code> 
       </row> 
       <row> 
        <month>03</month> 
        <year>2016</year> 
        <type>A</type> 
        <Id>10101</Id> 
        <Number>2</Number> 
        <code>A2004</code> 
       </row> 
       <row> 
        <month>04</month> 
        <year>2015</year> 
        <Id>10122</Id> 
        <Number>1</Number> 
        <code>A2004</code> 
       </row> 
      </table> 

Я пытаюсь группировать этот XML на уровне ID и номера внутри него.

  <test> 
       <xsl:for-each-group select="$table" group-by="Id"> 
        <xsl:variable name="var2_resultof_group_items" as="item()+" select="current-group()"/> 
        </xsl:variable> 
        <row> 
         <xsl:attribute name="Id"> 
          <xsl:value-of select="normalize-space(current-grouping-key())"/> 
         </xsl:attribute> 
         <xsl:for-each select="$var2_resultof_group_items"> 
          <xsl:attribute name="month"> 
           <xsl:value-of select="month"/> 
          </xsl:attribute> 
         </xsl:for-each> 
         <xsl:for-each select="$var2_resultof_group_items"> 
          <xsl:attribute name="year"> 
           <xsl:value-of select="year"/> 
          </xsl:attribute> 
         </xsl:for-each> 
         <xsl:for-each-group select="$var2_resultof_group_items" group-by="Number"> 
          <xsl:variable name="var1_resultof_group_items" as="item()+" select="current-group()"/> 
          <line> 
           <xsl:attribute name="number" select="current-grouping-key()"/> 
           <xsl:for-each select="$var1_resultof_group_items"> 
            <xsl:attribute name="code"> 
             <xsl:value-of select="code"/> 
            </xsl:attribute> 
           </xsl:for-each> 
          </line> 
         </xsl:for-each-group> 
        </row> 
       </xsl:for-each-group> 
      </test> 

Это выход я получаю с моей XSLT 2.0 кода (желаемый результат), но я не уверен, как выполнить это с помощью XSLT 1,0

  <test> 
       <row Id="10101" month="03" year="2016"> 
        <line Number="1" code="A2004"/> 
        <line Number="2" code="A2004"/> 
       </row> 
       <row Id="10122" month="04" year="2015"> 
        <line Number="1" code="A2004"/> 
       </row> 
      </test> 

Я могу использовать XLST 1,0 до получить до выхода ниже, но я не уверен, как реализовать группировку ID и затем Числа в нем:

  <test> 
       <row Id="10101" month="03" year="2016"> 
        <line Number="1" code="A2004"/> 
       </row> 
       <row Id="10101" month="03" year="2016"> 
        <line Number="2" code="A2004"/> 
       </row> 
       <row Id="10122" month="04" year="2015"> 
        <line Number="1" code="A2004"/> 
       </row> 
      </test> 
+0

Начать здесь: http://www.jenitennison.com/xslt/grouping/muenchian.html Затем посмотрите на многочисленные примеры группировки Muenchian, размещенные здесь на SO. –

ответ

0

Вы можете попробовать это muenchian groupingXSLT 1.0 решения:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:key name="kid" match="row" use="Id"/> 
    <xsl:template match="table"> 
     <test> 
      <xsl:for-each select="row [ 
           count (key('kid',./Id)[1] | .) = 1 ]"> 

       <xsl:variable name="this" select="."/> 
       <row> 
        <xsl:attribute name="Id"> 
         <xsl:value-of select="Id"/> 
        </xsl:attribute> 
        <xsl:attribute name="month"> 
         <xsl:value-of select="month"/> 
        </xsl:attribute> 
        <xsl:attribute name="year"> 
         <xsl:value-of select="year"/> 
        </xsl:attribute> 
        <xsl:for-each select="key('kid', $this/Id)"> 
         <line> 
          <xsl:attribute name="number" > 
           <xsl:value-of select="Number"/> 
          </xsl:attribute> 
          <xsl:attribute name="code"> 
           <xsl:value-of select="code"/> 
          </xsl:attribute> 
         </line> 
        </xsl:for-each> 
       </row> 
      </xsl:for-each> 
     </test> 
    </xsl:template> 
</xsl:stylesheet> 

С следующим выводом:

<test> 
    <row Id="10101" month="03" year="2016"> 
    <line number="1" code="A2004"/> 
    <line number="2" code="A2004"/> 
    </row> 
    <row Id="10122" month="04" year="2015"> 
    <line number="1" code="A2004"/> 
    </row> 
</test> 
+0

Это прекрасно работает. Не могли бы вы объяснить мне, что делает это выражение? ' 'Спасибо большое! – Cris3k

+0

Взгляните на [группирование муэнхиев] (http: //www.jenitennison.com/xslt/grouping/muenchian.html) (как указывал майкл.hor257k). * см., имеет ли узел, состоящий из двух узлов, один или два узла в нем - узлы не могут быть повторены в наборе узлов, поэтому, если в нем есть только один узел, то они должны быть одним и тем же узлом * –

1

Здесь гораздо проще, короче и почти полностью в "нажимного" стиль решения:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:key name="kRowById" match="row" use="Id"/> 

    <xsl:template match="/*"> 
    <test> 
     <xsl:apply-templates/> 
    </test> 
    </xsl:template> 

    <xsl:template match="row[generate-id() = generate-id(key('kRowById', Id)[1])]"> 
    <row id="{Id}"> 
     <xsl:apply-templates select="key('kRowById', Id)" mode="inGroup"/> 
    </row> 
    </xsl:template> 

    <xsl:template match="row" mode="inGroup"> 
    <line Number="{Number}" code="{code}"/> 
    </xsl:template> 
    <xsl:template match="text()"/> 
</xsl:stylesheet> 

Когда это преобразование применяется к предоставленному XML-документу:

<table> 
    <row> 
     <month>03</month> 
     <year>2016</year> 
     <Id>10101</Id> 
     <Number>1</Number> 
     <code>A2004</code> 
    </row> 
    <row> 
     <month>03</month> 
     <year>2016</year> 
     <type>A</type> 
     <Id>10101</Id> 
     <Number>2</Number> 
     <code>A2004</code> 
    </row> 
    <row> 
     <month>04</month> 
     <year>2015</year> 
     <Id>10122</Id> 
     <Number>1</Number> 
     <code>A2004</code> 
    </row> 
</table> 

разыскиваемый, правильный результат получается:

<test> 
    <row id="10101"> 
     <line Number="1" code="A2004"/> 
     <line Number="2" code="A2004"/> 
    </row> 
    <row id="10122"> 
     <line Number="1" code="A2004"/> 
    </row> 
</test> 

Объяснение:

  1. Muenchian группировка.

  2. Использование стандартной функции XSLT generate-id() для сравнения идентичности узлов.

  3. Использование АВТ (атрибут-значение) Шаблоны

  4. Использование режимов.

  5. Использование XSLT встроенных (так называемых «по умолчанию») шаблонов.

+0

Спасибо много для решения. Я все еще знаком с таблицей стилей push, и это отличный пример для меня. У меня есть вопрос, хотя одно из моих требований - установить минимальную длину строки переменной «code» равной «5». Есть ли простой способ сделать это в стиле push, когда источник предоставляет мне пустую строку? что-то вроде в xslt 1.0? – Cris3k

 Смежные вопросы

  • Нет связанных вопросов^_^