Xml 带计数的XSLT转换
如何使用xslt转换以下内容Xml 带计数的XSLT转换,xml,xslt,transformation,Xml,Xslt,Transformation,如何使用xslt转换以下内容 <blogger> <post> <text>...</text> <categories>Engineering, Internet, Sausages</catgories> </post> <post> <text>...</text> <categories>Internet, Sau
<blogger>
<post>
<text>...</text>
<categories>Engineering, Internet, Sausages</catgories>
</post>
<post>
<text>...</text>
<categories>Internet, Sausages</catgories>
</post>
<post>
<text>...</text>
<categories>Sausages</catgories>
</post>
</blogger>
<blogger>
<post>
<text>...</text>
<categories>
<category>Engineering</category>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Sausages</category>
</categories>
</post>
</blogger>
首先,更改xml
<blogger>
<post>
<text>...</text>
<categories>
<category>Engineering</category>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Sausages</category>
</categories>
</post>
</blogger>
创建data.xml
<blogger>
<post>
<text>...</text>
<categories>
<category>Engineering</category>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Sausages</category>
</categories>
</post>
</blogger>
...
工程类
互联网
香肠
...
互联网
香肠
...
香肠
然后编写xslt,创建transform.xslt
<blogger>
<post>
<text>...</text>
<categories>
<category>Engineering</category>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Sausages</category>
</categories>
</post>
</blogger>
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each select="//category">
<xsl:variable name="value" select="."/>
<xsl:if test="count(preceding::category[.=$value]) = 0">
<xsl:value-of select="."/>
<xsl:text> (</xsl:text>
<xsl:value-of select="count(//category[.=$value])"/>
<xsl:text>)</xsl:text><br/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
(
)
然后,您可以在internet explorer中打开data.xml,并获得以下结果:
<blogger>
<post>
<text>...</text>
<categories>
<category>Engineering</category>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Sausages</category>
</categories>
</post>
</blogger>
Engineering (1)Internet (2)Sausages (3)
工程(1)互联网(2)香肠(3)您需要的是:
<blogger>
<post>
<text>...</text>
<categories>
<category>Engineering</category>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Sausages</category>
</categories>
</post>
</blogger>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:template match="/">
<items>
<xsl:apply-templates select="/blogger/post/categories" />
</items>
</xsl:template>
<xsl:template match="categories">
<xsl:call-template name="split">
<xsl:with-param name="pString" select="." />
</xsl:call-template>
</xsl:template>
<!-- this splits a comma-delimited string into a series of <item>s -->
<xsl:template name="split">
<xsl:param name="pString" select="''" />
<xsl:variable name="vList" select="
concat($pString, ',')
" />
<xsl:variable name="vHead" select="
normalize-space(substring-before($vList ,','))
" />
<xsl:variable name="vTail" select="
normalize-space(substring-after($vList ,','))
" />
<xsl:if test="not($vHead = '')">
<item>
<xsl:value-of select="$vHead" />
</item>
<xsl:call-template name="split">
<xsl:with-param name="pString" select="$vTail" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
事实上,这是可以做到的,也不难。这将执行您希望它执行的操作:
<blogger>
<post>
<text>...</text>
<categories>
<category>Engineering</category>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Sausages</category>
</categories>
</post>
</blogger>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="fo msxsl">
<xsl:output encoding="UTF-8" indent="yes" method="xml"/>
<xsl:variable name="Separator">,</xsl:variable>
<xsl:template match="/">
<xsl:variable name="NodeList">
<xsl:apply-templates select="//categories"/>
</xsl:variable>
<xsl:variable name="Nodes" select="msxsl:node-set($NodeList)"/>
<html>
<head>
<title>Simple list</title>
</head>
<body>
<xsl:for-each select="$Nodes/Value">
<xsl:variable name="value" select="."/>
<xsl:if test="count(preceding::Value[.=$value]) = 0">
<xsl:value-of select="."/> (<xsl:value-of select="count($Nodes/Value[.=$value])"/>)<br/>
</xsl:if>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template match="categories" name="Whole">
<xsl:call-template name="Substring">
<xsl:with-param name="Value" select="normalize-space(.)"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="Substring">
<xsl:param name="Value"/>
<xsl:choose>
<xsl:when test="contains($Value, $Separator)">
<xsl:variable name="Before" select="normalize-space(substring-before($Value, $Separator))"/>
<xsl:variable name="After" select="normalize-space(substring-after($Value, $Separator))"/>
<Value>
<xsl:value-of select="$Before"/>
</Value>
<xsl:call-template name="Substring">
<xsl:with-param name="Value" select="$After"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<Value>
<xsl:value-of select="$Value"/>
</Value>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
,
简单列表
()
事实上,这是小菜一碟。:-) 不幸的是,我无法更改XML的结构,因为它来自其他地方。拥有现有的XML结构(至少对我来说)是不符合逻辑的。您可以要求您的xml源提供商更改其xml吗?否则,您可以预处理/细化XML,以获得运行所需xslt所需的内容。这很酷……最后一个想法是要将它们从高到低排序吗?3.2.1 etcAwww,对它们进行排序也不会那么困难,但我会把它作为其他人的练习。:-)为什么不发布有效的XML?我是说。。。这是一个剪切和粘贴的问题…它在源代码中是正确的;markdown错误地解释了缩进不足的行。必须补充的是,此代码适用于MXSML。如果使用另一个XSLT处理器,则需要另一个解决方案将变量转换为节点集。(虽然有些处理器不需要这样的转换。)但这也不是对组计数进行排序-需要两步操作来完成。哦,我只是注意到:模板名称(“整”)是不必要的。对组计数进行分组并不困难。只需将它们再次添加到新节点集。我的样式表已经分两步运行了。首先,它拆分字符串并将结果存储在节点集中。然后计算该节点集中的元素。您可以将其添加到第二个节点集中,并根据计数对其进行排序。基本上,您可以在一个样式表中执行两个步骤…嗯。。。是的,你可以这么做。也许我只是在分组和做一些没有扩展函数的事情时太过执着于键了对于小输入,“node-set()”和“count(count)(previous…)”可能足够快,但我认为它的伸缩性非常差。无论如何+从我这里得到1^^
<blogger>
<post>
<text>...</text>
<categories>
<category>Engineering</category>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Internet</category>
<category>Sausages</category>
</categories>
</post>
<post>
<text>...</text>
<categories>
<category>Sausages</category>
</categories>
</post>
</blogger>