Группировка узлов по соответствующему атрибуту

#xslt

#xslt

Вопрос:

Мой входной xml выглядит так, как показано ниже, мне нужно сгруппировать тег на основе атрибута id. Даже если атрибут id тега совпадает в следующей строке, он должен быть сгруппирован под предыдущим тегом.

 <Layouts>
<Layout id="1">
<Structure id="2000">
<Row id="1">
<Col id="125"/>
</Row>
<Row id="2">
<Col id="126"/>
</Row>
<Row id="3">
<Col id="125"/>
</Row>
</Structure>
</Layout>

<Layout id="2">
<Structure id="3000">
<Row id="1">
<Col id="125"/>
</Row>
<Row id="2">
<Col id="226"/>
</Row>
<Row id="3">
<Col id="226"/>
</Row>
<Row id="4">
<Col id="125"/>
</Row>
</Structure>
</Layout>
</Layouts>
  

Мой выходной XML должен выглядеть следующим образом,

 <Layouts>
<Layout id="1">
<Structure id="2000">
<Row id="1">
<Col id="125"/>
<Col id="125"/>
</Row>
<Row id="2">
<Col id="126"/>
</Row>          
</Structure>
</Layout>

<Layout id="2">
<Structure id="3000">
<Row id="1">
<Col id="125"/>
<Col id="125"/>
</Row>
<Row id="2">
<Col id="226"/>
<Col id="226"/>
</Row>          
</Structure>
</Layout>
</Layouts>
  

Как мы можем видеть, каждая строка должна быть сгруппирована с аналогичными значениями атрибута id и, наконец, она должна отображаться в одном.
Эта группировка должна выполняться только для каждого раздела.
Для каждого узла аналогичные идентификаторы должны быть сгруппированы внутри узла.
Я попробовал xsl:для каждой группы, но идентификаторы не группируются точно внутри. Может кто-нибудь, пожалуйста, помогите..

Комментарии:

1. Пожалуйста, выполните поиск по группировке XSLT — это, вероятно, наиболее часто задаваемый вопрос здесь. Обратите внимание, что ответы разные для XSLT 1.0 и 2.0.

2. Вы говорите, что пробовали xsl: для каждой группы, так что не могли бы вы показать XSLT, который вы пробовали до сих пор, пожалуйста? Не имеет значения, что это может не сработать. Возможно, вы не так уж далеки от решения! Спасибо!

3. Может ли у вас быть режим, превышающий один элемент «Col» на «строку» во входном XML?

Ответ №1:

Предполагая, что все, что вам нужно для группировки, это Col элементы, и вы можете использовать XSLT 2.0, вот таблица стилей:

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

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

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* , node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="Structure">
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <xsl:for-each-group select="Row" group-by="Col/@id">
      <xsl:copy>
        <xsl:apply-templates select="@* , current-group()/node()"/>
      </xsl:copy>
    </xsl:for-each-group>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>