组父节点并获得子节点的不同

时间:2013-07-29 16:39:43

标签: xslt

我想编写一个转换,它应该给出父节点和它的子节点的不同。

在给定的例子中,我期待不同的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>

请帮助区分Place collection和Spoc

1 个答案:

答案 0 :(得分:1)

看起来你已经意识到你必须在这里使用Muenchian分组,这很好,但你实际上需要总共进行三次分组。

首先,您正在寻找不同的 Item 元素。我会根据值对数据项进行分组调整

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

然后,只需对您当前的 xsl:apply-templates 进行一些小调整即可获得所需的“项目”

<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)"/>

请注意使用连接,因为您要在每个不同的中对不同的元素进行分组。

然后,要为给定的项目获取不同的区域元素,您可以这样做

<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>