使用XSLT非常容易实现这一点(不需要将结果捕获到变量中,也不需要使用特殊的命名模板):
I. XSLT 1.0:
<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=
"Locality/text() | CollectorAndNumber/text()
| Institution/text() | Distribution/text()
| Note/text()
"
>
<xsl:value-of select="."/>
<xsl:if test="not(position() = last())">,</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
当应用此转换器于以下 XML 文档时:
<root>
<record>
<Locality>Locality</Locality>
<CollectorAndNumber>CollectorAndNumber</CollectorAndNumber>
<Institution>Institution</Institution>
<Distribution>Distribution</Distribution>
<Note></Note>
<OtherStuff>Unimportant</OtherStuff>
</record>
</root>
产生了所需的结果:
Locality,CollectorAndNumber,Institution,Distribution
如果需要产生的元素不按文档顺序排序(这是问题中没有要求的,但被Tomalak提出),仍然可以轻松而优雅地实现:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:param name="porderedNames"
select="' CollectorAndNumber Locality Distribution Institution Note '"/>
<xsl:template match="/*/*">
<xsl:for-each select=
"*[contains($porderedNames, concat(' ',name(), ' '))]">
<xsl:sort data-type="number"
select="string-length(
substring-before($porderedNames,
concat(' ',name(), ' ')
)
)"/>
<xsl:value-of select="."/>
<xsl:if test="not(position() = last())">,</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
在这里,所需元素的名称及其顺序以字符串参数$porderedNames
的形式提供,其中包含所有所需名称的以空格分隔的列表。
当上述转换应用于同一XML文档时,将产生所需的结果:
CollectorAndNumber,Locality,Distribution,Institution
II. XSLT 2.0:
XSLT中这个任务甚至更简单(同样不需要使用特殊函数):
<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="," select=
"(Locality, CollectorAndNumber,
Institution, Distribution,
Note)[text()]" />
</xsl:template>
</xsl:stylesheet>
对同一份 XML 文档应用这个转换时,能够获得相同正确的结果:
Locality,CollectorAndNumber,Institution,Distribution
请注意,由于我们使用XPath 2.0序列类型(而不是XSLT 1.0解决方案中的联合),所以所需元素将按任意顺序生成,根据定义,该序列类型包含按任意(指定)顺序排列的项目。