Change format of comma delimited tags in xml using xslt?

廉价感情. 提交于 2019-12-24 08:56:20

问题


I have an xml doc that contains comma delimited tags like this...

<?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>

Is it possible, using xslt, to change the xml to display more like the code below where it separates the tag name and counts how many times the tag is referenced?

<?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> 

Thanks for any help.


回答1:


IIUC, there are two tasks here:

  1. Tokenize the tags;

  2. Count the occurrences of each tag.

The second task requires the output of the first one as its input - so we will need to do this in two passes:

<?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>

Note that this requires the EXSLT node-set() function, which is widely supported by XSLT 1.0 processors. If your processor supports the EXSLT tokenize() function, then you can use it instead of the tokenizing template. The output of that is already a node-set, so that would simplify the stylesheet considerably.



来源:https://stackoverflow.com/questions/21892330/change-format-of-comma-delimited-tags-in-xml-using-xslt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!