使用xslt更改xml中逗号分隔标签的格式? [英] Change format of comma delimited tags in xml using xslt?

查看:89
本文介绍了使用xslt更改xml中逗号分隔标签的格式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 <?xml version =1.0这是一个xml文档,其中包含以逗号分隔的标签。 encoding =utf-8?>> 
<网页>
< page>
< tags> AAMC 2013,Learning Health System,Cost< / tags>
< / page>
< page>
< tags> AAMC 2013,成本,创新< /标签>
< / page>
< page>
< tags> AAMC 2013,成本,创新< /标签>
< / page>
< / pages>

是否有可能使用xslt将xml更改为更像下面代码的分隔符标签名称并计算标签被引用的次数?

 <?xml version =1.0encoding =utf -8→> 
<网页>
< page>
< tag>
<名称> AAMC 2013< / name>
<金额> 3< /金额>
< / tag>
< tag>
<名称>学习健康系统< /名称>
<金额> 1< /金额>
< / tag>
< tag>
<名称>费用< /名称>
<金额> 3< /金额>
< / tag>
< / page>
< page>
< tag>
<名称> AAMC 2013< / name>
<金额> 3< /金额>
< / tag>
< tag>
<名称>费用< /名称>
<金额> 3< /金额>
< / tag>
< tag>
<名称>创新< /名称>
<金额> 2< /金额>
< / tag>
< / page>
< page>
< tag>
<名称> AAMC 2013< / name>
<金额> 3< /金额>
< / tag>
< tag>
<名称>费用< /名称>
<金额> 3< /金额>
< / tag>
< tag>
<名称>创新< /名称>
<金额> 2< /金额>
< / tag>
< / page>
< / pages>

感谢您的任何帮助。

解决方案IIUC,这里有两项任务:


  1. 标记标签;


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


  3. 第二个任务需要第一个输出作为输入 - 所以我们需要两次完成此操作:

     <? xml version =1.0encoding =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:key name =sametagmatch =tokenuse =。 />

    < xsl:template match =/>
    <! - 第一遍 - >
    < xsl:variable name =tagnames>
    < xsl:for-each select =pages / page>
    < page>
    < xsl:call-template name =tokenize>
    < xsl:with-param name =stringselect =tags/>
    < / xsl:call-template>
    < / page>
    < / xsl:for-each>
    < / xsl:variable>
    <! - 秒(最后)传球 - >
    <网页>
    < xsl:for-each select =$ tagnames-set / page>
    < page>
    < xsl:for-each select =token>
    < tag>
    < name>< xsl:value-of select =。 />< /名称>
    < 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 =delimiterselect =','/>
    < xsl:when test =contains($ string,$ delimiter)>
    < token>< xsl:value-of select =substring-before($ string,$ delimiter)/>< / token>
    <! - 递归调用 - >
    < xsl:call-template name =tokenize>
    < xsl:with-param name =delimiterselect =$ delimiter/>
    < / xsl:call-template>
    < / xsl:when>
    < xsl:otherwise>
    < token>< xsl:value-of select =$ string/>< / token>
    < / xsl:otherwise>
    < / xsl:template>

    < / xsl:stylesheet>

    请注意,这需要EXSLT node-set()函数,XSLT 1.0处理器。如果您的处理器支持EXSLT tokenize()函数,则可以使用它来代替标记化模板。它的输出已经是一个节点集,因此可以大大简化样式表。


    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.

    解决方案

    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.

    这篇关于使用xslt更改xml中逗号分隔标签的格式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆