XSLT 1.0 解决方案
这个 XSLT 1.0 样式表...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:variable name="strip-chars" select=""[]''"" />
<xsl:for-each select="*">
<xsl:copy>
<xsl:call-template name="tokenize">
<xsl:with-param name="content" select="concat(translate(@Icons,$strip-chars,''),',')" />
<xsl:with-param name="count" select="3" />
</xsl:call-template>
</xsl:copy>
</xsl:for-each>
</xsl:template>
<xsl:template name="tokenize">
<xsl:param name="content" />
<xsl:param name="count" />
<xsl:if test="contains($content,',') and $count > 0">
<img src="{substring-before($content,',')}" alt="" />
<xsl:call-template name="tokenize">
<xsl:with-param name="content" select="normalize-space(substring-after($content,','))" />
<xsl:with-param name="count" select="$count - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
...当应用于此输入文档时...
<t Icons="['http://www.test.com/image1.jpg',
'http://www.test.com/image2.jpg',
'http://www.test.com/image3.jpg',
'http://www.test.com/image4.jpg',
'http://www.test.com/image5.jpg']"/>
...将产生...
<t>
<img src="http://www.test.com/image1.jpg" alt="" />
<img src="http://www.test.com/image2.jpg" alt="" />
<img src="http://www.test.com/image3.jpg" alt="" />
</t>
当应用于这个简短的输入文档时......
<t Icons="['http://www.test.com/image1.jpg',
'http://www.test.com/image2.jpg']"/>
...产量...
<t>
<img src="http://www.test.com/image1.jpg" alt="" />
<img src="http://www.test.com/image2.jpg" alt="" />
</t>
笔记
在编辑时,Suresh 的解决方案不适用于图像数量为 3 或更少的第二个用例。
XSLT 2.0 解决方案
使用具有这样的样式表的 XSLT 2.0 可以更简单、更有效和更可扩展地达到相同的结果......
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:for-each select="*">
<xsl:copy>
<xsl:variable name="image-elements" as="element()*">
<xsl:analyze-string select="@Icons" regex="'([^']*)'(,|\])" >
<xsl:matching-substring>
<img src="{regex-group(1)}" alt="" />
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:copy-of select="$image-elements[not(position() > 3)]" />
</xsl:copy>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
XSLT 2.0 XPATH 解决方案
出于兴趣,这里是使用纯 XPATH 的 XSLT 2.0 的变体。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:for-each select="*">
<xsl:copy>
<xsl:for-each select="(for $i in tokenize(@Icons,',') return
replace($i,'.*''([^'']*)''.*','$1'))
[not(position() > 3)]">
<img src="{.}" alt="" />
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
更新和评论 Dimitre 的解决方案
祝贺 Dimitre 提供了更简洁的 XSLT 2.0 解决方案。他使用了与我的稍有不同的输入,其中没有方括号。查看 Dimitre 的解决方案,我可以看到一个调整,使其更小。
这个 XSLT 2.0 样式表是对 Dimitre 解决方案的调整,是所有解决方案中最严格的,作为奖励,它适用于我的输入文档形式和他的形式,以生成相同且正确的结果文档。
<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 select="tokenize(/*/@Icons, '\[?\s*''\s*,?\]?')[.][position() le 3]">
<img src="{.}" alt=""/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>