我是新来的XSLT和手动更改将需要大量的时间。
<GroupData ID="xxx" Key="4" Temp="yyy">
<ItemData ID="zzz" Value="3"/>
</GroupData>
<GroupData ID="xxx" Key="4" Temp="yyy">
<ItemData ID="www" Value="1982"/>
</GroupData>
我想有同一组中的这些多重GroupData节点的孩子的,也就是说,
<GroupData ID="xxx" Key="4" Temp="yyy">
<ItemData ID="zzz" Value="3"/>
<ItemData ID="www" Value="1982"/>
</GroupData>
所以,我需要合并/合并/匹配他们两个GroupData的ID和密钥属性(这些变化在文件中)。 还有些没有一个关键属性。 我怎样才能做到这一点? 我看了一些其他线程(例如,在C#中,但我没有说在我手上),我检查W3学校,但这些都是非常基本的例子。 我使用的是最新的XML工具2.3.2 R908的Unicode(BETA4)记事本++应用可能的转换(不知道它是否支持XSLT2.0或者XSLT1.0)。
编辑:尝试下面的建议和各种事情我坚持,因为它具有多层次,多possiblly不具有唯一的ID后:...
这XSLT 1.0转换 :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kGDByIdKey" match="GroupData"
use="concat(@ID, '+', @Key)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"GroupData
[generate-id()
=
generate-id(key('kGDByIdKey', concat(@ID, '+', @Key))[1])
]">
<xsl:copy>
<xsl:apply-templates select=
"@*|key('kGDByIdKey', concat(@ID, '+', @Key))/node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="GroupData"/>
</xsl:stylesheet>
当应用这个XML文档上:
<t>
<GroupData ID="xxx" Key="4" Temp="yyy">
<ItemData ID="zzz" Value="3"/>
</GroupData>
<GroupData ID="yyy" Key="4" Temp="yyy">
<ItemData ID="abc" Value="3"/>
</GroupData>
<GroupData ID="zzz" Temp="yyy">
<ItemData ID="pqr" Value="1982"/>
</GroupData>
<GroupData ID="xxx" Key="4" Temp="yyy">
<ItemData ID="www" Value="1982"/>
</GroupData>
<GroupData ID="yyy" Key="4" Temp="yyy">
<ItemData ID="def" Value="1982"/>
</GroupData>
<GroupData ID="zzz" Temp="yyy">
<ItemData ID="tuv" Value="1982"/>
</GroupData>
</t>
产生想要的,正确的结果 :
<t>
<GroupData ID="xxx" Key="4" Temp="yyy">
<ItemData ID="zzz" Value="3"/>
<ItemData ID="www" Value="1982"/>
</GroupData>
<GroupData ID="yyy" Key="4" Temp="yyy">
<ItemData ID="abc" Value="3"/>
<ItemData ID="def" Value="1982"/>
</GroupData>
<GroupData ID="zzz" Temp="yyy">
<ItemData ID="pqr" Value="1982"/>
<ItemData ID="tuv" Value="1982"/>
</GroupData>
</t>
说明 :
正确使用的Muenchian分组的方法和身份规则 。
如果它是XSLT 2.0那么你可以使用一个嵌套<xsl:for-each-group>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<Groups>
<xsl:for-each-group select="/Groups/GroupData" group-by="@ID">
<xsl:for-each-group select="current-group()" group-by="if(@Key) then @Key else 'no key'">
<GroupData>
<!-- Copy attributes off the *first* GroupData element in the group -->
<xsl:copy-of select="current-group()[1]/@*"/>
<!-- Copy ItemData children from *all* GroupData elements in the group -->
<xsl:copy-of select="current-group()/ItemData" />
</GroupData>
</xsl:for-each-group>
</xsl:for-each-group>
</Groups>
</xsl:template>
</xsl:stylesheet>
(我假定输入文件具有根元素<Groups>
和不使用的命名空间)。
如果它是XSLT 1.0,那么你需要使用Muenchian分组的 :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="group-data" match="GroupData" use="concat(@ID, '___', @Key)" />
<xsl:template match="/">
<Groups>
<!--
Iterate over a node set containing just one GroupData element for
each combination of ID and Key
-->
<xsl:for-each select="/Groups/GroupData[count( . | key('group-data', concat(@ID, '___', @Key))[1]) = 1]">
<GroupData>
<!-- Copy attributes from the "prototype" GroupData -->
<xsl:copy-of select="@*"/>
<!--
Copy ItemData children from *all* GroupData elements with matching
ID/Key
-->
<xsl:copy-of select="key('group-data', concat(@ID, '___', @Key))/ItemData" />
</GroupData>
</xsl:for-each>
</Groups>
</xsl:template>
</xsl:stylesheet>
在这里我做创建了基于综合双方的ID和密钥属性的单一分组通key
的值{ID}___{Key}
。