2016-10-27 6 views
0

У меня есть удручающе плоский XML, который выглядит следующим образом:Преобразование плоской иерархии в иерархии вложенных в глубину XSLT

<groups> 
    <group id="1" depth="1" /> 
    <group id="2" depth="2" /> 
    <group id="3" depth="2" /> 
    <group id="4" depth="3" /> 
    <group id="5" depth="2" /> 
    <group id="6" depth="3" /> 
</groups> 

Максимальное значение depth, как представляется, будет 5.

который я хотел бы включить в XML, который выглядит следующим образом:

<groups> 
    <group id="1" depth="1"> 
     <group id="2" depth="2"> 
     </group> 
     <group id="3" depth="2"> 
      <group id="4" depth="3"> 
      </group> 
     </group> 
     <group id="5" depth="2"> 
      <group id="6" depth="3"> 
      </group> 
     </group> 
    </group> 
</groups> 

Я думаю мне нужно использовать xsl:key, а затем для каждого parentDepth соответствует следующим узлов, которые имеют depth = parentDepth + 1до Я достигаю узла с depth <= parentDepth, но я не уверен, как реализовать такое правило.

Я полагаю, что другой логический подход может состоять в том, чтобы начать с «дна» и найти самый последний узел с depth = childDepth - 1, но я не уверен, что это может быть достигнуто даже в XSLT.

Я также не уверен, что это можно сделать рекурсивно для каждой глубины?

Я использую XSLT 1.0.

+0

Возможная Дубликат [Плоский к вложенной структуры на основе значения атрибута с использованием XSLT] (http://stackoverflow.com/questions/11113161/flat-to-nested-structure- based-on-attribute-value-use-xslt) Существует также решение XSLT 1.0! – uL1

ответ

0

Я думаю, что нужно использовать xsl:key, а затем для каждого parentDepth матча следующих узлов, которые имеют depth = parentDepth + 1

Нет, вы должны смотреть на него в противоположном направлении: пусть каждый ребенок находит своего родителя и изучает его уникальный идентификатор, поэтому он может быть вызван им.

XSLT-1,0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="child" match="group" use="generate-id(preceding-sibling::group[@depth=current()/@depth - 1][1])" /> 

<xsl:template match="/groups"> 
    <xsl:copy> 
     <xsl:apply-templates select="group[@depth=1]"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="group"> 
    <group id="{@id}" depth="{@depth}"> 
     <xsl:apply-templates select="key('child', generate-id())"/> 
    </group> 
</xsl:template> 

</xsl:stylesheet> 
+0

Хмм, это только дает мне '. Нужно ли мне возвращаться? – ThunderFrame

+0

Он рекурсирует, если вы не заметили. Посмотрите, как он работает здесь: http://xsltransform.net/3NSSEuZ –

+0

Хмм, MSXML, похоже, не нравится. возможно, мне нужно явно переключить SelectionLanguage на xpath? – ThunderFrame