我正在尝试在XSLT中获取自定义生成的字符串序列的唯一值。 手头的问题很不寻常,因为我必须首先在“。”上分割一个字符串。并且最后一点的印章,这工作正常,但使用XSLT 2.0 distinct-values获取唯一值不是。
给出一些输入
<TreeNumberList>
<TreeNumber>A01.001.001</TreeNumber>
<TreeNumber>A01.001.002</TreeNumber>
<TreeNumber>A01.001.003</TreeNumber>
<TreeNumber>A01.002.111</TreeNumber>
</TreeNumberList>
所需的输出是
的可迭代序列A01.001, A01.002
到目前为止,我有以下功能
<xsl:function name="func:strip-last">
<xsl:param name="str"></xsl:param>
<xsl:value-of select="substring($str, 1, string-length($str) - 1)"></xsl:value-of>
</xsl:function>
<xsl:function name="func:parent-of">
<xsl:param name="nodes"></xsl:param>
<xsl:variable name="output">
<xsl:for-each select="$nodes">
<xsl:variable name="parent">
<xsl:for-each select="tokenize(., '\.')">
<xsl:if test="position() != last()">
<xsl:value-of select="."></xsl:value-of>
<xsl:text>.</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<tmp><xsl:value-of select="func:strip-last($parent))"></xsl:value-of></tmp>
</xsl:for-each>
</xsl:variable>
<xsl:sequence select="distinct-values($output/*)"></xsl:sequence>
</xsl:function>
但这不会返回一组不同的元素,而是返回所有元素的序列。由于TreeNumbers本身不是唯一的,但是通过键查找检索到的某个名称将是最终的代码。 (对于那些认可标记的人来说,它是MeSH XML的一部分)
我还试图使用键控索引或group-by来表示唯一性,但这些索引与文档片段不相符。
答案 0 :(得分:1)
你必须有功能吗?你能创建一个具有序列的变量吗?
示例...
XML输入
<TreeNumberList>
<TreeNumber>A01.001.001</TreeNumber>
<TreeNumber>A01.001.002</TreeNumber>
<TreeNumber>A01.001.003</TreeNumber>
<TreeNumber>A01.002.111</TreeNumber>
</TreeNumberList>
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vAllTreeNumbers">
<xsl:for-each select="/*/TreeNumber">
<xsl:analyze-string select="." regex="(.*)\.[^.]*$">
<xsl:matching-substring>
<xsl:value-of select="concat(regex-group(1),' ')"/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="vUniqueTreeNumbers" select="distinct-values(tokenize(normalize-space($vAllTreeNumbers),' '))"/>
<xsl:template match="/">
<results>
<!--This demonstrates that each value is part of a sequence.-->
<xsl:for-each select="$vUniqueTreeNumbers">
<item>
<xsl:value-of select="."/>
</item>
</xsl:for-each>
</results>
</xsl:template>
</xsl:stylesheet>
XML输出(仅用于演示序列)
<results>
<item>A01.001</item>
<item>A01.002</item>
</results>
这是另一个返回相同结果的选项......
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:local="local"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:function name="local:getUniqueTreeNumbers">
<xsl:param name="pNodes"/>
<xsl:variable name="vAllTreeNumbers">
<xsl:for-each select="$pNodes">
<xsl:analyze-string select="." regex="(.*)\.[^.]*$">
<xsl:matching-substring>
<xsl:value-of select="concat(regex-group(1),' ')"/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:for-each>
</xsl:variable>
<xsl:sequence select="distinct-values(tokenize(normalize-space($vAllTreeNumbers),' '))"></xsl:sequence>
</xsl:function>
<xsl:template match="/">
<results>
<!--This demonstrates that each value is part of an iterable sequence.-->
<xsl:for-each select="local:getUniqueTreeNumbers(*/TreeNumber)">
<item>
<xsl:value-of select="."/>
</item>
</xsl:for-each>
</results>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
以下表达式将一组不同的值作为字符串序列提供:
distinct-values(TreeNumber/replace(., '\..*$', ''))