javascript - XSLT 处理后生成位置数组

标签 javascript xslt

前言:我正在 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];

说明:

  1. 这是一个两遍解决方案。在第一遍中,我们“按原样”复制所有元素,但向每个 Row 添加一个 pos 属性。这个新属性的值是此 Row 在其兄弟 Row 元素中的相对位置。

  2. 在每个 Row 的第二遍中,我们获取其主 Row (使用 key 进行非常快速( O(1) )访问),然后我们输出该master的pos属性的值。

关于javascript - XSLT 处理后生成位置数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8539517/

相关文章:

javascript - react : setInterval Not working after one interval

java - 有没有办法通过知道相对于java中文本节点的索引来查找xml中的特定位置?

XML 数据类型转换

xslt - 使用XSLT添加必需节点

xslt - XSL。只返回第一个非空元素

xml - 使用 XSLT 将单词包装在标签中

javascript - 根据字典替换字符串中的短语

javascript - 单击菜单项后恢复汉堡包动画

javascript - jQGrid,如何使列在添加对话框中可编辑但在(内联)编辑期间不可编辑

javascript - 无法在谷歌文档文件中找到函数错误