使用 xslt 更改 xml 中逗号分隔标记的格式



>我有一个包含逗号分隔标签的 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> 

感谢您的任何帮助。

IIUC,这里有两个任务:

  1. 标记标签;

  2. 计算每个标签的出现次数。

第二个任务需要第一个任务的输出作为其输入 - 因此我们需要分两次执行此操作:

<?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() 函数,则可以使用它来代替标记化模板。它的输出已经是一个节点集,所以这将大大简化样式表。

相关内容

  • 没有找到相关文章

最新更新