xml 节点计数和出现 - XSL
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1500555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Node count and occurence - XSL
提问by user182093
I need to write generic xsl that would take in an xml document and output the count of nodes and their names. So if I have a file like the following:
我需要编写通用的 xsl,它会接收一个 xml 文档并输出节点的数量及其名称。所以如果我有一个像下面这样的文件:
<assets>
<asset>
<type>hardware</type>
<item>
<name>HP laptop</name>
<value>799</value>
</item>
<item>
<name>server</name>
<value>1000</value>
</item>
<item>
<name>ViewSonic Monitor</name>
<value>399</value>
</item>
</asset>
<asset>
<type>software</type>
<item>
<name>Windows Vista</name>
<value>399</value>
</item>
<item>
<name>Office XP</name>
<value>499</value>
</item>
<item>
<name>Windows 7</name>
<value>399</value>
</item>
<item>
<name>MS Project Professional 2007</name>
<value>299</value>
</item>
</asset>
</assets>
The output would be:
输出将是:
<output>
<node name="assets" count="1"/>
<node name="asset" count="2"/>
<node name= "type" count="??"/>
<node name="item" count=??/>
<node name="name" count=??/>
<node name="value" count=??/>
</output>
回答by Gavin Miller
You'll want to use the count function:
你会想要使用计数功能:
<xsl:value-of select="count(assets/asset)" />
So your code would look like:
所以你的代码看起来像:
Assets: <xsl:value-of select="count(assets)" />
Asset: <xsl:value-of select="count(assets/asset)" />
Item: <xsl:value-of select="count(assets/asset/item)" />
回答by Jukka Matilainen
The generic solution for input containing nodes with any names can be done using the Muenchianmethod:
包含任何名称节点的输入的通用解决方案可以使用Muenchian方法完成:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="nodes-by-name" match="*" use="name()"/>
<xsl:template match="/">
<output>
<xsl:for-each select="//*[count(.|key('nodes-by-name', name())[1]) = 1]">
<node name="{name()}" count="{count(key('nodes-by-name', name()))}"/>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
Explanation: Using xsl:key, create a mapping from names to the nodes having that name. Then iterate through all unique names, and output the node count for the name. The main trick here is how to iterate through unique names. See the linked page for an explanation of the count(.|foo)=1idiom used to figure out if foois a node set containing only the context node.
说明:使用xsl:key,创建从名称到具有该名称的节点的映射。然后遍历所有唯一名称,并输出该名称的节点数。这里的主要技巧是如何遍历唯一名称。有关count(.|foo)=1用于确定是否foo为仅包含上下文节点的节点集的习语的解释,请参阅链接页面。
回答by Mohamed
This is my solution using XSLT 2.0 :
这是我使用 XSLT 2.0 的解决方案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:element name="output">
<xsl:for-each-group select="//*" group-by="name()">
<xsl:element name="node">
<xsl:attribute name="name">
<xsl:value-of select="current-grouping-key()"/>
</xsl:attribute>
<xsl:attribute name="count">
<xsl:value-of select="count(current-group())"/>
</xsl:attribute>
</xsl:element>
</xsl:for-each-group>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

