Генерация массива позиций после обработки XSLT - PullRequest
2 голосов
/ 17 декабря 2011

Предисловие : у меня есть таблица, которую я создаю в XSLT, у которой есть дочерние элементы (это древовидное представление в виде таблицы).Я обрабатывал 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 () для получения нужного уровня работает нормально, но как я могу гарантировать, что этот массив будет сгенерирован в конце обработки, или будет ли способ добавить массив во время обработки?Это вообще возможно?

Ответы [ 2 ]

2 голосов
/ 17 декабря 2011

Ответ @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. Это двухпроходное решение.На первом этапе мы копируем все элементы «как есть», но добавляем атрибут pos к каждому Row.Значением этого нового атрибута является относительная позиция этого Row среди его родных элементов Row элементов.

  2. Во втором проходе для каждого Row мы получаем его мастер Row (используя ключ для очень быстрого доступа (O (1))), а затем мы выводим значение атрибута pos этого мастера.

1 голос
/ 17 декабря 2011

Следующая таблица стилей связывает каждый Row с предшествующим ему Row, который имеет тот же MasterID:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/">
        <xsl:text>var map1 = [</xsl:text>
        <xsl:apply-templates select="/*/Row"/>
        <xsl:text>];</xsl:text>
    </xsl:template>
    <xsl:template match="Row[ID=MasterID]">0</xsl:template>
    <xsl:template match="Row">
        <xsl:text>, </xsl:text>
        <xsl:value-of select="count(preceding-sibling::Row[
            ID=current()/MasterID]/preceding-sibling::Row) + 1."/>
    </xsl:template>
</xsl:stylesheet>

Применяется к этому входу:

<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 при его обработке, который может плохо работать с очень большими документами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...