[英]refresh position using xslt for multiple elements with same name
The source xml document: 源xml文档:
<item>
<p languageCode="en">en</p>
<p languageCode="fr">fr</p>
<c languageCode="de">de</c>
<c languageCode="nl">nl</c>
</item>
The needed result of the transformation must be this xml document: 转换所需的结果必须是以下xml文档:
<item>
<p pos="1">en</p>
<p pos="2">fr</p>
<c pos="1">de</c>
<c pos="2">nl</c>
</item>
using xslt is it possible achieve it? 使用xslt是否有可能实现?
In XSLT 2.0 you can do: 在XSLT 2.0中,您可以执行以下操作:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/item">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="name()">
<xsl:apply-templates select="current-group()"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="p | c">
<xsl:copy>
<xsl:attribute name="pos" select="position()"/>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XSLT 1.0: 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:template match="/*">
<item><xsl:apply-templates/></item>
</xsl:template>
<xsl:template match="/*/*">
<xsl:copy>
<xsl:attribute name="pos">
<xsl:value-of select="count(preceding-sibling::*[name()=name(current())])+1"/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XSLT 2.0 : 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:strip-space elements="*"/>
<xsl:template match="/*">
<item><xsl:apply-templates/></item>
</xsl:template>
<xsl:template match="/*/*">
<xsl:copy>
<xsl:attribute name="pos"
select="count(preceding-sibling::*[name()=name(current())])+1"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Another XSLT 2.0 solution : 另一个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:key name="kByName" match="/*/*" use="name()"/>
<xsl:template match="/*">
<item><xsl:apply-templates/></item>
</xsl:template>
<xsl:template match="/*/*">
<xsl:copy>
<xsl:attribute name="pos"
select="index-of(key('kByName', name())/generate-id(), generate-id())"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
When applied on the provided XML document : 当应用于提供的XML文档时 :
<item>
<p languageCode="en">en</p>
<p languageCode="fr">fr</p>
<c languageCode="de">de</c>
<c languageCode="nl">nl</c>
</item>
All three solutions produce the wanted, correct result: 这三种解决方案都能产生想要的正确结果:
<item>
<p pos="1">en</p>
<p pos="2">fr</p>
<c pos="1">de</c>
<c pos="2">nl</c>
</item>
Do note : 注意事项 :
All these solutions are generic -- they don't depend on the names, number, number of names or order of elements. 所有这些解决方案都是通用的 -它们不依赖于名称,数量,名称数量或元素顺序。
For example, when applied on the following XML document: 例如,当应用于以下XML文档时:
<item>
<p languageCode="en">en</p>
<p languageCode="fr">fr</p>
<c languageCode="de">de</c>
<c languageCode="nl">nl</c>
<d languageCode="es">es</d>
<d languageCode="bg">bg</d>
<d languageCode="pl">pl</d>
</item>
all three solutions produce the wanted, correct result : 这三种解决方案都能产生想要的正确结果 :
<item>
<p pos="1">en</p>
<p pos="2">fr</p>
<c pos="1">de</c>
<c pos="2">nl</c>
<d pos="1">es</d>
<d pos="2">bg</d>
<d pos="3">pl</d>
</item>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.