我一直在尝试根据属性计数将此列表放在层次结构上,但我无法做到。起初是尝试在一个阶段,分阶段进行,但在使用previous-sibling和follow-sibling时我一直遇到同样的问题。
这就是我所拥有的
<body>
<element count="2"/>
<element count="2"/>
<element count="2"/>
<element count="2"/>
<element count="4"/>
<element count="4"/>
<element count="6"/>
<element count="4"/>
<element count="2"/>
<element count="4"/>
<element count="2"/>
<element count="4"/>
<element count="6"/>
<element count="6"/>
<element count="4"/>
<element count="2"/>
</body>
这就是我想要的
<body>
<element count="2"/>
<element count="2"/>
<element count="2"/>
<element count="2">
<element count="4"/>
<element count="4">
<element count="6"/>
</element>
<element count="4"/>
</element>
<element count="2">
<element count="4"/>
</element>
<element count="2">
<element count="4">
<element count="6"/>
<element count="6"/>
</element>
<element count="4"/>
</element>
<element count="2"/>
</body>
任何帮助将不胜感激,谢谢!
答案 0 :(得分:1)
如果您知道count
属性的值分别为2,4,6,..
,那么您就知道初始计数和计数之间的差异,这很容易:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf">
<xsl:output indent="yes"/>
<xsl:function name="mf:group" as="element(element)*">
<xsl:param name="elements" as="element(element)*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:param name="step" as="xs:integer"/>
<xsl:for-each-group select="$elements" group-starting-with="element[@count = $level]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:sequence select="mf:group(current-group() except ., $level + $step, $step)"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:function>
<xsl:template match="body">
<xsl:copy>
<xsl:sequence select="mf:group(element, 2, 2)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
这是一个可能的XSLT 1.0解决方案。这里的诀窍是使用键将每个element
链接到最近的前一个兄弟,该兄弟的count
值非常小。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:strip-space elements="*" />
<xsl:output method="xml" indent="yes" />
<xsl:key name="childrenByParent" match="element"
use="generate-id(preceding-sibling::element[@count < current()/@count][1])" />
<xsl:template match="/body">
<body>
<xsl:apply-templates select="key('childrenByParent', '')" />
</body>
</xsl:template>
<xsl:template match="element">
<element>
<xsl:copy-of select="@*" />
<xsl:apply-templates select="key('childrenByParent', generate-id())" />
</element>
</xsl:template>
</xsl:stylesheet>
起点key('childrenByParent', '')
有效,因为我们需要从没有“父”的元素开始,即preceding-sibling::element[@count < current()/@count][1]
选择空节点的元素设置,以及空节点集is defined to be the empty string的generate-id
。
如果元素可以被命名为任何内容,只要它们具有count
属性,您就会在评论中询问需要更改的内容。在这种情况下,您只需要对键定义进行一些小改动,使其(a)匹配任何带count
的元素,(b)查找带有 any 的父元素名称而不仅仅是element
:
<xsl:key name="childrenByParent" match="*[@count]"
use="generate-id(preceding-sibling::*[@count < current()/@count][1])" />
并向第二个模板提供更通用的match
模式,并使用xsl:copy
代替硬编码元素名称来创建:
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates select="key('childrenByParent', generate-id())" />
</xsl:copy>
</xsl:template>