我有xml看起来像这样 –
<Root> <Fields> <Field name="abc" displayName="aaa" /> <Field name="pqr" displayName="ppp" /> <Field name="abc" displayName="aaa" /> <Field name="xyz" displayName="zzz" /> </Fields> </Root>
我希望输出只包含那些具有重复name-displayName组合的元素,如果有的话 –
<Root> <Fields> <Field name="abc" displayName="aaa" /> <Field name="abc" displayName="aaa" /> </Fields> </Root>
我怎么能用XSLT做到这一点?
这种转变:
原文链接:https://www.f2er.com/xml/292023.html<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="kFieldByName" match="Field" use="concat(@name,'+',@displayName)"/> <xsl:template match= "Field[generate-id() = generate-id(key('kFieldByName',concat(@name,@displayName) )[2]) ] "> <xsl:copy-of select= "key('kFieldByName',@displayName))"/> </xsl:template> </xsl:stylesheet>
当应用于提供的XML文档时:
<Root> <Fields> <Field name="abc" displayName="aaa" /> <Field name="pqr" displayName="ppp" /> <Field name="abc" displayName="aaa" /> <Field name="xyz" displayName="zzz" /> </Fields> </Root>
产生想要的结果:
<Field name="abc" displayName="aaa"/> <Field name="abc" displayName="aaa"/>
说明:
> Muenchian grouping使用复合键(在name和displayName属性上).
>代码中唯一的模板匹配任何Field元素,它是相应组中的第二个元素.然后,在模板的主体内部输出整个组.
> Muenchian分组是在XSLT 1.0中进行分组的有效方法.密钥用于提高效率.
>另见我对this question的回答.
II. XSLT 2.0解决方案:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/"> <xsl:for-each-group select="/*/*/Field" group-by="concat(@name,@displayName)"> <xsl:sequence select="current-group()[current-group()[2]]"/> </xsl:for-each-group> </xsl:template> </xsl:stylesheet>
当在提供的XML文档(如上所示)上应用此转换时,将再次生成所需的正确结果:
<Field name="abc" displayName="aaa"/> <Field name="abc" displayName="aaa"/>
说明: