2013-07-29 2 views
-1

Я хотел бы написать преобразование, которое должно отличать родительский узел и отдельный его дочерний узел.Группируйте родительские узлы и получайте отличные от дочерних узлов

В данном примере я ожидаю отличную от Spocs и коллекцию мест. Но не могли бы вы предоставить решение:

Вход:

<DataCollection> 
<Data> 
<Item>Item1</Item> 
<Price>6</Price> 
<Area>Area1</Area> 
<Contact>P1</Contact> 
</Data> 
<Data> 
<Item>Item1</Item> 
<Price>6.5</Price> 
<Area>Area2</Area> 
<Contact>P1</Contact> 
</Data> 
<Data> 
<Item>Item1</Item> 
<Price>6</Price> 
<Area>Area1</Area> 
<Contact>P2</Contact> 
</Data> 
<Data> 
<Item>Item2</Item> 
<Price>6</Price> 
<Area>Area3</Area> 
<Contact>P1</Contact> 
</Data> 
<Data> 
<Item>Item2</Item> 
<Price>6</Price> 
<Area>Area1</Area> 
<Contact>P2</Contact> 
</Data> 
<Data> 
<Item>Item2</Item> 
<Price>6</Price> 
<Area>Area2</Area> 
<Contact>P2</Contact> 
</Data> 
</DataCollection> 

Ожидаемый результат:

<?xml version="1.0" encoding="UTF-8"?> 
<MainTable1> 
<Record> 
<ItemNumber>Item1</ItemNumber> 
<Rate>6</Rate> 
<PlaceCollcection> 
<Place>Area1</Place> 
<Place>Area2</Place>   
</PlaceCollcection> 
<Spocs>   
<Spoc>P1</Spoc> 
<Spoc>P2</Spoc> 
</Spocs> 
</Record> 
<Record> 
<ItemNumber>Item2</ItemNumber> 
<Rate>6</Rate> 
<PlaceCollcection> 
<Place>Area3</Place> 
<Place>Area1</Place> 
<Place>Area2</Place> 
</PlaceCollcection> 
<Spocs> 
<Spoc>P1</Spoc>   
<Spoc>P2</Spoc> 
</Spocs> 
</Record> 

Xsl Что я с помощью:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:key name="ItemKey" match="Item" use="."/> 
<xsl:template match="/DataCollection"> 
<MainTable1> 
<xsl:apply-templates select="Data/Item[generate-id() = 
generate-id(key('ItemKey',.)1])]"/> 
</MainTable1> 
</xsl:template> 
<xsl:template match="Item"> 
<xsl:variable name="currentGroup" select="."/> 
<Record> 
<ItemNumber> 
<xsl:value-of select="../Item"/> 
</ItemNumber> 
<Rate> 
<xsl:value-of select="../Price"/> 
</Rate> 
<PlaceCollcection> 
<xsl:for-each select="key('ItemKey', $currentGroup)"> 
<Place> 
<xsl:value-of select="../Area"/> 
</Place> 
</xsl:for-each> 
</PlaceCollcection> 
<Spocs> 
<xsl:for-each select="key('ItemKey', $currentGroup)"> 
<Spoc> 
<xsl:value-of select="../Contact"/> 
</Spoc> 
</xsl:for-each> 
</Spocs> 
</Record> 
</xsl:template> 
</xsl:stylesheet> 

Пожалуйста, помогите получить отличную от коллекции мест и Spoc

ответ

0

Похоже, вы поняли, что здесь вам нужно использовать группировку Muenchian, что хорошо, но вам действительно нужно сделать три серии группировок.

Во-первых, вы ищете различные Пункт элементов. Я хотел бы сделать твик, чтобы сгруппировать данные элементов их Пункта значение

<xsl:key name="ItemKey" match="Data" use="Item"/> 

Тогда, это просто небольшая настройка для текущего XSL: Наносить-шаблоны, чтобы получить различные «элементы» вам нужно

<xsl:apply-templates select="Data[generate-id() = generate-id(key('ItemKey',Item)[1])]"/> 

Теперь, в рамках каждого отдельного Пункт вы группируя отдельно Площадь и Контакта, так что вам нужны два отдельных ключи здесь

<xsl:key name="AreaKey" match="Data" use="concat(Item, '|', Area)"/> 
<xsl:key name="ContactKey" match="Data" use="concat(Item, '|', Contact)"/> 

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

Затем, чтобы получить различные Area элементов для данного Пункта, вы могли бы сделать это

<xsl:for-each select="key('ItemKey',Item)[generate-id() = generate-id(key('AreaKey', concat(Item, '|', Area))[1])]"> 

И точно так же, чтобы получить различные Контакты элементов, вы могли бы сделать это:

<xsl:for-each select="key('ItemKey',Item)[generate-id() = generate-id(key('ContactKey', concat(Item, '|', Contact))[1])]"> 

Попробуйте следующий XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="ItemKey" match="Data" use="Item"/> 
    <xsl:key name="AreaKey" match="Data" use="concat(Item, '|', Area)"/> 
    <xsl:key name="ContactKey" match="Data" use="concat(Item, '|', Contact)"/> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="/DataCollection"> 
     <MainTable1> 
     <xsl:apply-templates select="Data[generate-id() = generate-id(key('ItemKey',Item)[1])]"/> 
     </MainTable1> 
    </xsl:template> 
    <xsl:template match="Data"> 
     <Record> 
     <ItemNumber> 
      <xsl:value-of select="Item"/> 
     </ItemNumber> 
     <Rate> 
      <xsl:value-of select="Price"/> 
     </Rate> 
     <PlaceCollcection> 
      <xsl:for-each select="key('ItemKey',Item)[generate-id() = generate-id(key('AreaKey', concat(Item, '|', Area))[1])]"> 
       <Place> 
        <xsl:value-of select="Area"/> 
       </Place> 
      </xsl:for-each> 
     </PlaceCollcection> 
     <Spocs> 
      <xsl:for-each select="key('ItemKey',Item)[generate-id() = generate-id(key('ContactKey', concat(Item, '|', Contact))[1])]"> 
       <Spoc> 
        <xsl:value-of select="Contact"/> 
       </Spoc> 
      </xsl:for-each> 
     </Spocs> 
     </Record> 
    </xsl:template> 
</xsl:stylesheet> 

Применительно к вашему XML, следующий выход

<MainTable1> 
    <Record> 
     <ItemNumber>Item1</ItemNumber> 
     <Rate>6</Rate> 
     <PlaceCollcection> 
     <Place>Area1</Place> 
     <Place>Area2</Place> 
     </PlaceCollcection> 
     <Spocs> 
     <Spoc>P1</Spoc> 
     <Spoc>P2</Spoc> 
     </Spocs> 
    </Record> 
    <Record> 
     <ItemNumber>Item2</ItemNumber> 
     <Rate>6</Rate> 
     <PlaceCollcection> 
     <Place>Area3</Place> 
     <Place>Area1</Place> 
     <Place>Area2</Place> 
     </PlaceCollcection> 
     <Spocs> 
     <Spoc>P1</Spoc> 
     <Spoc>P2</Spoc> 
     </Spocs> 
    </Record> 
</MainTable1> 
Смежные вопросы