XSL отдельные подузлы - PullRequest
       0

XSL отдельные подузлы

1 голос
/ 07 декабря 2011

у меня есть и xml

<Top>
    <Node1>
        <Class1>
            <Test name="test1"></Test>
            <Test name="test2"></Test>
        </Class1>
    </Node1>
    <Node2>
        <Class1>
            <Test name="test1"></Test>
            <Test name="test2"></Test>
        </Class1>
    </Node2>
</Top>

Желаемый результат:

test1 - Node1 && Node2

test2 - Node1 && Node2

Iпробовал использовать Distinct, но я делаю что-то не так.

Может ли кто-нибудь помочь мне с этим ..

Спасибо, Гириш

1 Ответ

1 голос
/ 07 декабря 2011

I. Вот простое решение XSLT 1.0, использующее мюнхенский метод группировки :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kTestByName" match="Test"
          use="@name"/>

 <xsl:template match=
  "Test
     [generate-id()
     =
      generate-id(key('kTestByName', @name)[1])
     ]
  ">
  <xsl:value-of select=
  "concat(@name, ' -- ')"/>

  <xsl:apply-templates mode="group"
      select="key('kTestByName', @name)"/>
  <xsl:text>&#xA;</xsl:text>
 </xsl:template>

 <xsl:template match="Test" mode="group">
  <xsl:if test="position() > 1"> &amp;&amp; </xsl:if>
  <xsl:value-of select="name(../..)"/>
 </xsl:template>
</xsl:stylesheet>

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

<Top>
    <Node1>
        <Class1>
            <Test name="test1"></Test>
            <Test name="test2"></Test>
        </Class1>
    </Node1>
    <Node2>
        <Class1>
            <Test name="test1"></Test>
            <Test name="test2"></Test>
        </Class1>
    </Node2>
</Top>

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

test1 -- Node1 && Node2
test2 -- Node1 && Node2

II. Решение XSLT 2.0 с использованием <xsl:for-each-group> и функциями current-group() и current-grouping-key()

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output method="text"/>

 <xsl:template match="/*">
  <xsl:for-each-group select="*/*/Test"
                      group-by="@name">
   <xsl:value-of select=
   "concat(current-grouping-key(), ' -- ')"/>

   <xsl:apply-templates select="current-group()"/>
   <xsl:text>&#xA;</xsl:text>
  </xsl:for-each-group>
 </xsl:template>

 <xsl:template match="Test">
  <xsl:if test="position() > 1"> &amp;&amp; </xsl:if>
  <xsl:value-of select="name(../..)"/>
 </xsl:template>
</xsl:stylesheet>

когда это преобразование XSLT 2.0 применяется к тому же XML-документу (см. Выше), получается тот же требуемый и правильный результат :

test1 -- Node1 && Node2
test2 -- Node1 && Node2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...