我理解这是多次发布的一个常见问题,但不幸的是,我无法找到任何提议方法的确切解决方案:
以下是我的XML的样子:
<root>
<parent>
<table>
<attr ......>
<type t="enumone">
<info>
<name .....>
</info>
</attr>
<attr>
<type t="int">
<range min="1" max="255"/>
</type>
<info>
<name .....>
</info>
</attr>
<attr>
<type t="string">
<info>
<name .....>
</info>
</attr>
<attr ......>
<type t="enumtwo">
<info>
<name .....>
</info>
</attr>
<attr>
<type t="float">
<range min="1.0" max="25.5"/>
</type>
<info>
<name .....>
</info>
</attr>
<attr>
<type t="int">
<info>
<name .....>
</info>
</attr>
<attr>
<type t="enumone">
<info>
<name .....>
</info>
</attr>
<attr>
<type t="enumthree">
<info>
<name .....>
</info>
</attr>
<attr>
<type t="enumone">
<info>
<name .....>
</info>
</attr>
</parent>
</root>
目的是使用XSLT从“type”元素中检索一次属性“@t”:
Using for-each-group:
<xsl-template match="/root/parent">
<xsl:for-each select="table">
<xsl:for-each-group select="//type" group-by="@t">
<xsl:copy-of select="current-group( )[1]"/>
</xsl:for-each-group>
</xsl:for-each>
<xsl-template>
但我没有输出!我相信有些瑕疵。
使用distinct-values():
<xsl:for-each select="distinct-values(type/@t)">
<xsl:sort/>
<xsl:value-of select="."/> <xsl:call-template name="newline"/>
</xsl:for-each>
仍然没有理想的输出。
预期输出为:
enumone
int
string
enumtwo
float
enumthree
感谢这方面的任何帮助。
答案 0 :(得分:2)
输入样本不是格式良好的XML,但如果您真的只想要所有t
元素的不同type
属性值,那么
<xsl:template match="/">
<xsl:value-of select="distinct-values(//type/@t)" separator=" "/>
</xsl:template>
足以使用XSLT 2.0。
如果您还想要对不同的值进行排序,那么请执行
<xsl:template match="/">
<xsl:value-of separator=" ">
<xsl:perform-sort select="distinct-values(//type/@t)">
<xsl:sort select="."/>
</xsl:perform-sort>
</xsl:value-of>
</xsl:template>
提供一个完整的例子,输入为
<root>
<foo>
<type t="int"/>
</foo>
<bar>
<type t="enum"/>
</bar>
<foobar>
<foo>
<type t="enum">
<x/>
</type>
</foo>
</foobar>
<foo>
<type t="string"/>
</foo>
</root>
样式表
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:value-of separator=" ">
<xsl:perform-sort select="distinct-values(//type/@t)">
<xsl:sort select="."/>
</xsl:perform-sort>
</xsl:value-of>
</xsl:template>
</xsl:stylesheet>
输出
enum
int
string
答案 1 :(得分:0)
只需将您的代码修改为:
<xsl:template match="/">
<xsl:for-each-group select="//type" group-by="@t">
<xsl:copy-of select="current-group( )[1]"/>
</xsl:for-each-group>
</xsl:template>
完整转型:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:for-each-group select="//type" group-by="@t">
<xsl:copy-of select="current-group( )[1]"/>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
应用于格式良好的XML文档:
<root>
<foo>
<type t="int"/>
</foo>
<bar>
<type t="enum"/>
</bar>
<foobar>
<foo>
<type t="enum">
<x/>
</type>
</foo>
</foobar>
<foo>
<type t="string"/>
</foo>
</root>
产生了正确的结果:
<type t="int"/>
<type t="enum"/>
<type t="string"/>