问题类似于此,earlier question 哪个Dimitre已经回答了。响应xml略有修改。但是这次,我们需要从重复块中取出一个元素。不知道我们是否可以在这里使用xsl键功能。
我的输入xml
<M>
<a>
<b>
<c f="123">
<key>Al</key>
<e NO="678">
<f>Y</f>
<g>
<h>FTO</h>
</g>
</e>
</c>
</b>
</a>
<a>
<b>
<c f="123">
<key>Al</key>
<e NO="678">
<f>Y</f>
<g>
<h>FTO</h>
</g>
</e>
</c>
</b>
</a>
<a>
<b>
<c f="567">
<key>Al</key>
<e NO="678">
<f>Y</f>
<g>
<h>FTO</h>
</g>
</e>
</c>
</b>
</a>
<a>
<b>
<somethingelse/>
</b>
</a>
</M>
我想要的输出xml - 请注意,除了删除副本之外,我们还需要从重复块中获取关键元素。它可能是也可能不一样。
<M>
<a>
<b>
<c f="123">
<key>Al</key>
<key>Al</key>
<e NO="678">
<f>Y</f>
<g>
<h>FTO</h>
</g>
</e>
</c>
</b>
</a>
<a>
<b>
<c f="567">
<key>Al</key>
<e NO="678">
<f>Y</f>
<g>
<h>FTO</h>
</g>
</e>
</c>
</b>
</a>
<a>
<b>
<somethingelse/>
</b>
</a>
</M>
答案 0 :(得分:1)
此转化:
<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="kAByC-F" match="a" use="*/c/@f"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"a[*/c
and
not(generate-id()
=
generate-id(key('kAByC-F', */c/@f)[1])
)
]"/>
<xsl:template match="a/b/c[@f]">
<c f="{@f}">
<xsl:apply-templates select="key('kAByC-F', @f)/b/c/key"/>
<xsl:apply-templates select="*[not(self::key)]"/>
</c>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档:
<M>
<a>
<b>
<c f="123">
<key>Al</key>
<e NO="678">
<f>Y</f>
<g>
<h>FTO</h>
</g>
</e>
</c>
</b>
</a>
<a>
<b>
<c f="123">
<key>Al</key>
<e NO="678">
<f>Y</f>
<g>
<h>FTO</h>
</g>
</e>
</c>
</b>
</a>
<a>
<b>
<c f="567">
<key>Al</key>
<e NO="678">
<f>Y</f>
<g>
<h>FTO</h>
</g>
</e>
</c>
</b>
</a>
<a>
<b>
<somethingelse/>
</b>
</a>
</M>
生成想要的正确结果:
<M>
<a>
<b>
<c f="123">
<key>Al</key>
<key>Al</key>
<e NO="678">
<f>Y</f>
<g>
<h>FTO</h>
</g>
</e>
</c>
</b>
</a>
<a>
<b>
<c f="567">
<key>Al</key>
<e NO="678">
<f>Y</f>
<g>
<h>FTO</h>
</g>
</e>
</c>
</b>
</a>
<a>
<b>
<somethingelse/>
</b>
</a>
</M>
<强>解释强>:
identity rule “按原样”复制每个节点。它被两个匹配特定节点的模板覆盖。
第一个覆盖模板会删除使用密钥( Muenchian grouping method )指定的不是第一个a
元素的所有a
元素。
第二个覆盖模板匹配并处理未删除的c
孙子(通过第一个覆盖模板)a
元素。