前言:我正在 XSLT 中创建一个具有子项的表(它是表形式的 TreeView )。我手动处理隐藏/显示子节点的JS,但它很快就变得一团糟并且难以维护。我开始玩JQTreeTable .
这是一个示例输入(与 JSFiddle 链接匹配): http://pastebin.com/NQVHsy69
问题:JQTreeTable 需要通过数组了解节点之间的关系。它应该是这样的:http://jsfiddle.net/vt7Xd/30/
如果你看看 JavaScript:
var map1 = [0, 1, 1, 1, 1, 1, 6, 1 ];
^ 5600 ^ 5601 ^ 5602 ^ 5603 ^ 5604 ^ 5605 ^ 5606 ^ 5607
这些是职位/关系标识符。第一个元素是根 (0),接下来的几个元素是第一行的子元素。那么第 7 行是第 6 行的子行。
我需要在 XSLT 中生成这个数组。使用position()来获得正确的级别效果很好,但是我如何保证这个数组是在处理结束时生成的,或者是否有办法在处理过程中附加到数组?这可行吗?
最佳答案
@lwburk 的答案是一个很好的答案,但它的速度是二次方的 ( O(N^2) )。
这是一个简单的线性速度 ( O(N) ) 解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<xsl:output method="text"/>
<xsl:key name="kRowById" match="Row"
use="ID"/>
<xsl:variable name="vRows" select="/*/*"/>
<xsl:variable name="vTopIndex" select="1"/>
<xsl:template match="Row" mode="pass1">
<Row pos="{position()}">
<xsl:copy-of select="node()"/>
</Row>
</xsl:template>
<xsl:variable name="vrtfPass1">
<xsl:apply-templates select="/*/Row" mode="pass1"/>
</xsl:variable>
<xsl:variable name="vPass1" select=
"ext:node-set($vrtfPass1)/*"/>
<xsl:template match="/">
var map1 = [ <xsl:text/>
<xsl:apply-templates select="$vPass1"/>
<xsl:text>];</xsl:text>
</xsl:template>
<xsl:template match="Row">
<xsl:if test="position() > 1">, </xsl:if>
<xsl:value-of select=
"key('kRowById', MasterID)/@pos
-
(MasterID = ID)
"/>
</xsl:template>
</xsl:stylesheet>
应用于此 XML 文档时(问题中未内联提供 XML 文档!!!):
<Rows>
<Row>
<ID>5600</ID>
<MasterID>5600</MasterID>
<Name>A Product</Name>
<Owner>RyanB_Admin</Owner>
<CompletionPercentage>1</CompletionPercentage>
</Row>
<Row>
<ID>5601</ID>
<MasterID>5600</MasterID>
<Name>Requirements Gathering</Name>
<Owner>RyanB_Admin</Owner>
<CompletionPercentage>100</CompletionPercentage>
</Row>
<Row>
<ID>5602</ID>
<MasterID>5600</MasterID>
<Name>Design</Name>
<Owner>RyanB_Admin</Owner>
<CompletionPercentage>0</CompletionPercentage>
</Row>
<Row>
<ID>5603</ID>
<MasterID>5600</MasterID>
<Name>Development</Name>
<Owner>RyanB_Admin</Owner>
<CompletionPercentage>0</CompletionPercentage>
</Row>
<Row>
<ID>5604</ID>
<MasterID>5600</MasterID>
<Name>Testing</Name>
<Owner>RyanB_Admin</Owner>
<CompletionPercentage>0</CompletionPercentage>
</Row>
<Row>
<ID>5605</ID>
<MasterID>5600</MasterID>
<Name>Documentation</Name>
<Owner>RyanB_Admin</Owner>
<CompletionPercentage>0</CompletionPercentage>
</Row>
<Row>
<ID>5606</ID>
<MasterID>5605</MasterID>
<Name>Special documentation</Name>
<Owner>RyanB_Admin</Owner>
<CompletionPercentage>0</CompletionPercentage>
</Row>
<Row>
<ID>5607</ID>
<MasterID>5600</MasterID>
<Name>Implementation</Name>
<Owner>RyanB_Admin</Owner>
<CompletionPercentage>0</CompletionPercentage>
</Row>
</Rows>
产生了想要的正确结果:
var map1 = [ 0, 1, 1, 1, 1, 1, 6, 1];
说明:
这是一个两遍解决方案。在第一遍中,我们“按原样”复制所有元素,但向每个
Row
添加一个pos
属性。这个新属性的值是此Row
在其兄弟Row
元素中的相对位置。在每个
Row
的第二遍中,我们获取其主Row
(使用 key 进行非常快速( O(1) )访问),然后我们输出该master的pos
属性的值。
关于javascript - XSLT 处理后生成位置数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8539517/