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

请帮助区分 Place collection 和 Spoc

4

1 回答 1

1

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

首先,您正在寻找不同的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])]"/>

现在,在每个不同的Item中,您分别在AreaContact上进行分组,因此您需要两个单独的键

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

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

然后,要获得给定Item的不同Area元素,您可以这样做

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

同样,要获得不同的Contact元素,您可以这样做:

<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>
于 2013-07-29T22:52:32.513 回答