我有一个xml文档,其中包含逗号分隔的标签,如...
<?xml version="1.0" encoding="utf-8" ?>
<pages>
<page>
<tags>AAMC 2013, Learning Health System, Cost</tags>
</page>
<page>
<tags>AAMC 2013, Cost, Innovation</tags>
</page>
<page>
<tags>AAMC 2013, Cost, Innovation</tags>
</page>
</pages>
是否有可能使用xslt更改xml以显示更像下面的代码,它分隔标记名称并计算标记被引用的次数?
<?xml version="1.0" encoding="utf-8" ?>
<pages>
<page>
<tag>
<name>AAMC 2013</name>
<amount>3</amount>
</tag>
<tag>
<name>Learning Health System</name>
<amount>1</amount>
</tag>
<tag>
<name>Cost</name>
<amount>3</amount>
</tag>
</page>
<page>
<tag>
<name>AAMC 2013</name>
<amount>3</amount>
</tag>
<tag>
<name>Cost</name>
<amount>3</amount>
</tag>
<tag>
<name>Innovation</name>
<amount>2</amount>
</tag>
</page>
<page>
<tag>
<name>AAMC 2013</name>
<amount>3</amount>
</tag>
<tag>
<name>Cost</name>
<amount>3</amount>
</tag>
<tag>
<name>Innovation</name>
<amount>2</amount>
</tag>
</page>
</pages>
感谢您的帮助。
答案 0 :(得分:0)
IIUC,这里有两项任务:
标记标记;
计算每个标签的出现次数。
第二个任务需要输出第一个任务作为输入 - 所以我们需要两次通过:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="sametag" match="token" use="." />
<xsl:template match="/">
<!-- first pass -->
<xsl:variable name="tagnames">
<xsl:for-each select="pages/page">
<page>
<xsl:call-template name="tokenize">
<xsl:with-param name="string" select="tags" />
</xsl:call-template>
</page>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="tagnames-set" select="exsl:node-set($tagnames)" />
<!-- second (final) pass -->
<pages>
<xsl:for-each select="$tagnames-set/page">
<page>
<xsl:for-each select="token">
<tag>
<name><xsl:value-of select="." /></name>
<amount><xsl:value-of select="count(key('sametag', .))" /></amount>
</tag>
</xsl:for-each>
</page>
</xsl:for-each>
</pages>
</xsl:template>
<xsl:template name="tokenize">
<xsl:param name="string"/>
<xsl:param name="delimiter" select="', '"/>
<xsl:choose>
<xsl:when test="contains($string, $delimiter)">
<token><xsl:value-of select="substring-before($string, $delimiter)" /></token>
<!-- recursive call -->
<xsl:call-template name="tokenize">
<xsl:with-param name="string" select="substring-after($string, $delimiter)" />
<xsl:with-param name="delimiter" select="$delimiter" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<token><xsl:value-of select="$string"/></token>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
请注意,这需要EXSLT node-set()函数,XSLT 1.0处理器广泛支持该函数。如果您的处理器支持EXSLT tokenize()函数,那么您可以使用它而不是标记化模板。它的输出已经是一个节点集,因此可以大大简化样式表。