从大型层次结构中提取一个深度级别的智能方法是什么?想象一下以下制表符分隔的分层文本列表:
plants
fruits
apples
bananas
cherries
trees
oaks
maples
vegetables
onions
peppers
目标是仅输出具有一个深度级别的子列表:
plants
fruits
trees
vegetables
fruits
apples
bananas
cherries
trees
oaks
maples
vegetables
onions
peppers
应该在Mac上以及更大/更深的文件上工作。例如,这是一个更大的文件:
life
animals
mammals
dogs
cats
rabbits
fish
salmon
birds
plants
fruits
apples
bananas
cherries
mangoes
trees
oaks
maples
birch
pine
vegetables
onions
peppers
这将是较大输入的输出:
life
animals
plants
animals
mammals
fish
birds
mammals
dogs
cats
rabbits
fish
salmon
plants
fruits
trees
vegetables
fruits
apples
bananas
cherries
mangoes
trees
oaks
maples
birch
pine
vegetables
onions
peppers
答案 0 :(得分:1)
正如您已将问题标记为XSLT,我发布了一个XSLT 3.0解决方案,该解决方案应该与商业版本的Saxon 9.6(例如oXygen提供)或Saxon 9.7或Exselt一起使用:
<?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"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs math mf"
version="3.0">
<xsl:param name="text-uri" as="xs:string" select="'test2016030301.txt'"/>
<xsl:param name="indent" as="xs:string" select="'	'"/>
<xsl:output method="text"/>
<xsl:function name="mf:group" as="element(item)*">
<xsl:param name="lines" as="xs:string*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:for-each-group select="$lines" group-starting-with=".[. instance of xs:string and matches(., '^' || string-join((1 to $level)!$indent) || '\w')]">
<item data="{normalize-space()}">
<xsl:sequence select="mf:group(current-group()[position() gt 1], $level + 1)"/>
</item>
</xsl:for-each-group>
</xsl:function>
<xsl:template name="main" match="/">
<xsl:apply-templates select="mf:group(unparsed-text-lines($text-uri), 0)"/>
</xsl:template>
<xsl:template match="item">
<xsl:value-of select="@data, */($indent || @data)" separator=" "/>
<xsl:text> </xsl:text>
<xsl:apply-templates select="item[item]"/>
</xsl:template>
</xsl:stylesheet>
使用it:main
调用XSLT,并将文本文件的URI作为参数text-uri
。