2014-02-19 131 views
1

我有一个包含逗号分隔标签像这样的XML文档...使用xslt更改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

什么版本的xslt? –

+0

我使用的是xslt-1.0 – Jonathan

回答

0

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节点集()函数,这受到XSLT 1.0处理器的广泛支持。如果您的处理器支持EXSLT tokenize()函数,则可以使用它来代替标记化模板。它的输出已经是一个节点集,所以可以大大简化样式表。

+0

感谢您的回复。我尝试了一些与众不同的东西,并且改变了我的问题以更有意义......我想。对不起,我是新来的。 – Jonathan

+0

@Jonathan请再次编​​辑您的问题,并确保输入和输出XML文档都是有效的;现在他们都缺少一个根元素。我会自己添加一个,但是您已经有页面内的页面,恐怕我的示例不适合您的真实数据。 –

+0

对不起,页面太多。 – Jonathan