XSLT для преобразования XML с группировкой значения с одинаковыми тегами - PullRequest
1 голос
/ 26 марта 2012

У меня есть XML, который показывает значения с полем, значения которого выглядят следующим образом:

<data>
    <currentRow>
      <columnValue>usa</columnValue>
      <columnValue>ma</columnValue>
      <columnValue>boston</columnValue>
      <columnValue>bob</columnValue>
    </currentRow>
    <currentRow>
      <columnValue>usa</columnValue>
      <columnValue>ma</columnValue>
      <columnValue>boston</columnValue>
      <columnValue>george</columnValue>
    </currentRow>
    <currentRow>
      <columnValue>usa</columnValue>
      <columnValue>ny</columnValue>
      <columnValue>nyc</columnValue>
      <columnValue>mary</columnValue>
    </currentRow>
  </data>

Я хочу сгенерировать создание XML, которое выглядит как

<Class>
  <Student>
    <Country>usa</Country>
    <State>ma</State>
    <City>boston</City>
       <name>bob</name>
       <name>george</name>
  </Student>
  <Student>
    <Country>usa</Country>
    <State>ny</State>
    <City>nyc</City>
       <name>mary</name>
  </Student>
<Class>

InКороче говоря, у меня есть два вопроса:

  1. Я хочу перебрать текущие строки, чтобы сгенерировать общий XMl
  2. Я хочу сгруппировать имена учеников по месту их проживания, сначала погород, затем штат, а затем страна

Есть идеи, как мне это сделать?

1 Ответ

1 голос
/ 26 марта 2012

В следующей таблице стилей используется метод Мюнхена для группировки элементов currentRow по значениям первых 3 columnValue элементов.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>

    <!--Create a key grouping on the concatenated values of 
        country, state, and city separated by '-'-->
    <xsl:key name="students-by-country-state-city" 
             match="currentRow"
             use="concat(columnValue[1], 
                         '-', 
                         columnValue[2], 
                         '-', 
                         columnValue[3])"/>

    <xsl:template match="data">
        <Class>
            <!--apply templates to the first item in each grouping of items -->
            <xsl:apply-templates
                select="currentRow[generate-id() =
                                   generate-id(
                                     key('students-by-country-state-city', 
                                         concat(columnValue[1],
                                         '-', 
                                         columnValue[2],  
                                         '-', 
                                         columnValue[3]))[1]
                                   )]"
            />
        </Class>
    </xsl:template>

    <xsl:template match="currentRow">
        <Student>
            <Country>
                <xsl:value-of select="columnValue[1]"/>
            </Country>
            <State>
                <xsl:value-of select="columnValue[2]"/>
            </State>
            <City>
                <xsl:value-of select="columnValue[3]"/>
            </City>

            <!-- find all of the names for this grouping -->
            <xsl:for-each
                select="key('students-by-country-state-city', 
                                    concat(columnValue[1], 
                                           '-', 
                                           columnValue[2],  
                                           '-', 
                                           columnValue[3]))/columnValue[4]">
                <name>
                    <xsl:value-of select="."/>
                </name>
            </xsl:for-each>
        </Student>
    </xsl:template>

</xsl:stylesheet>
...