XSLT: сделать группу в два раза, сначала в пределах одного и того же тега, а затем по 2 различным тегам - PullRequest
0 голосов
/ 31 августа 2018

Я хочу сгруппировать следующий XML:

<DataSet>
  <FirstNode>
    <UniqueKey>111</UniqueKey> 
    <OtherKey>552</OtherKey>
  </FirstNode>
  <FirstNode> 
    <UniqueKey>123</UniqueKey> 
    <OtherKey>552</OtherKey>
  </FirstNode>
  <FirstNode> 
    <UniqueKey>154</UniqueKey> 
    <OtherKey>553</OtherKey>
  </FirstNode>
  <SecondNode>
    <FirstNodeKey>111</FirstNodeKey>
  </SecondNode>
  <SecondNode>
    <FirstNodeKey>123></FirstNodeKey>
  </SecondNode>
  <SecondNode>
    <FirstNodeKey>154></FirstNodeKey>
  </SecondNode>
</DataSet>

Я хочу создать следующий xml с XSLT:

  <DataSet>
      <FirstNode>
        <UniqueKey>111</UniqueKey> 
        <OtherKey>552</OtherKey>
      </FirstNode>
      <FirstNode> 
        <UniqueKey>123</UniqueKey> 
        <OtherKey>552</OtherKey>
      </FirstNode>
      <SecondNode>
        <FirstNodeKey>111</FirstNodeKey>
      </SecondNode>
      <SecondNode>
        <FirstNodeKey>123></FirstNodeKey>
      </SecondNode>
 </DataSet>

<DataSet>
      <FirstNode> 
        <UniqueKey>154</UniqueKey> 
        <OtherKey>553</OtherKey>
      </FirstNode>
      <SecondNode>
        <FirstNodeKey>154></FirstNodeKey>
      </SecondNode>
 </DataSet>

По сути, я хочу сначала сгруппировать FirstNodes по OtherKey, а затем по UniqueKey и FirstNodeKey. Тогда каждый должен быть заключен в <DataSet></DataSet>. Могу ли я сделать это с помощью группировки?

Заранее спасибо за помощь!

1 Ответ

0 голосов
/ 31 августа 2018

Кажется, вы просто хотите сгруппировать элементы FirstNode по дочернему элементу OtherKey, а затем ссылаться на любые элементы SecondNode на основе current-group()/UniqueKey:

<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:key name="second" match="SecondNode" use="FirstNodeKey"/>

  <xsl:template match="DataSet">
     <xsl:variable name="ds" select="."/>
     <xsl:for-each-group select="FirstNode" group-by="OtherKey">
         <xsl:copy select="$ds">
             <xsl:copy-of select="current-group(), key('second', current-group()/UniqueKey, .)"/>
         </xsl:copy>
     </xsl:for-each-group>
  </xsl:template>

</xsl:stylesheet>

Это XSLT 3, работающий с Saxon 9.8 (пример на https://xsltfiddle.liberty -development.net / 3NzcBtw ) или Altova 2018, для XSLT 2 вы можете записать

         <xsl:copy select="$ds">
             <xsl:copy-of select="current-group(), key('second', current-group()/UniqueKey, .)"/>
         </xsl:copy>

а

<DataSet> 
     <xsl:copy-of select="current-group(), key('second', current-group()/UniqueKey, $ds)"/>
</DataSet>

и, конечно, если есть другие узлы для обработки, замените объявление xsl:mode шаблоном идентификации.

...