我有一些类似于以下的XML数据,将存储在xslt 1中的变量中。
<?xml version="1.0" encoding="utf-8"?>
<ItemCollection>
<Item>
<Number>1</Number>
<Data>string 1</Data>
</Item>
<Item>
<Number>1</Number>
<Data>string 2</Data>
</Item>
<Item>
<Number>2</Number>
<Data>string 3</Data>
</Item>
<Item>
<Number>2</Number>
<Data>string 3</Data>
</Item>
<Item>
<Number>3</Number>
<Data>string 4</Data>
</Item>
</ItemCollection>
此变量名为$collection
。
我想转换数据,因此它将具有如下所示的结构:
<?xml version="1.0" encoding="utf-8"?>
<ItemCollection>
<Item>
<Number>1</Number>
<Data>string 1</Data>
<Data>string 2</Data>
</Item>
<Item>
<Number>2</Number>
<Data>string 3</Data>
</Item>
<Item>
<Number>3</Number>
<Data>string 4</Data>
</Item>
</ItemCollection>
即:Data
具有相同兄弟Number
(值)的Item
应归为一组。如果Number
和Data
两者相似,则应完全删除Item
&s的重复项。在原始XML中,每个Number
都有完全一个Data
和一个Number
- 我想要更改它,因此它仍然只有一个{{1} },但有几个Data
。
如上所述,XML数据是变量中的,位于上方。我尝试了不同的事情,例如使用两个 这是我目前拥有的XSLT(只有一个片段,如果需要可以发布更多内容) 编辑: 非常感谢,答案。我意识到结果包含重复的内容: 还有一种简单的方法可以删除这些吗?我尝试声明另一个 但是删除了所有项目,而不仅仅是重复项目。 xsl:for-each
来迭代变量两次(使用exsl:node-set($collection)//Item
),但这只产生了数据的排序顺序,这没什么用处。 / p>
<xsl:variable name="collection" select="'XMl DATA'"/>
<xsl:variable name="final">
<xsl:for-each select="exsl:node-set($collection)//Item">
<xsl:variable name="outer" select="."/>
<xsl:for-each select="exsl:node-set($collection)//Item">
<xsl:variable name="inner" select="."/>
<xsl:if test="$inner = $outer">
<Item>
<xsl:value-of select="$outer/Number"/>
<xsl:copy-of select="$inner/Data"/>
</Item>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
<xsl:copy-of select="$final" />
<Item>
<Number>2039205</Number>
<Data>String 1</Data>
<Data>String 1</Data>
<Data>String 1</Data>
</tns:Item>
xsl:key
<xsl:key name="item-by-data" match="Item" use="Data"/>
然后执行: <xsl:template match="Item">
<xsl:copy>
<xsl:copy-of select="Number| key('item-by-data', Number)/Data[generate-id() = generate-id(key('item-by-data', Data)[1])]"/>
</xsl:copy>
</xsl:template>
答案 0 :(得分:1)
在您获得的节点集上使用Muenchian grouping,例如<xsl:param name="col-ns" select="exsl:node-set($collection)"/>
,即定义一个键
<xsl:key name="item-by-number" match="Item" use="Number"/>
然后
<xsl:template match="ItemCollection">
<xsl:copy>
<xsl:apply-templates select="Item[generate-id() = generate-id(key('item-by-number', Number)[1])]"/>
</xsl:copy>
</xsl:template>
和
<xsl:template match="Item">
<xsl:copy>
<xsl:copy-of select="Number | key('item-by-number', Number)/Data"/>
</xsl:copy>
</xsl:template>
然后您只需要在需要转换内容的地方使用<xsl:apply-templates select="$col-ns/node()"/>
。
完整样本位于http://xsltransform.net/gWmuiJc。
如果您还想删除重复的Data
,则可以使用<xsl:key name="numbered-items-by-data" match="Item" use="concat(Number, '|', Data)"/>
和
<xsl:template match="Item">
<xsl:copy>
<xsl:copy-of select="Number | key('item-by-number', Number)[generate-id() = generate-id(key('numbered-items-by-data', concat(Number, '|', Data))[1])]/Data"/>
</xsl:copy>
</xsl:template>