我想编写一个转换,它应该给出父节点和它的子节点的不同。
在给定的例子中,我期待不同的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
答案 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>