2009-02-28 10 views
1

J'ai comme xml:XML à table, comment obtenir la position() du nœud de contexte à l'ancêtre spécifié (s)

<A1> 
    <B1> 
    <C1> 
    <C2> 
    <C3> 
    </B1> 
    <B2> 
    <C4> 
    <C5> 
    <C6> 
    </B2> 
</A1> 
<A2> 
    <B3> 
    <C7> 
    <C8> 
    <C9> 
    </B3> 
    <B4> 
    <C10> 
    <C11> 
    <C12> 
    </B4> 
</A2> 

je dois transformer en table avec des lignes imbriquées:

<table border="yes"> 
<tr> 
    <td>A1</td> 
    <td>B1</td> 
    <td>C1</td> 
</tr> 
<tr> 
    <td></td> 
    <td></td> 
    <td>C2</td> 
</tr> 
<tr> 
<td></td> 
<td></td> 
<td>C3</td> 
</tr> 
<tr> 
<td></td> 
<td>B2</td> 
<td>C3</td> 
</tr> 
<tr> 
<td></td> 
<td></td> 
<td>C4</td> 
</tr> 

A et B n'apparaissent que s'ils sont nouveaux (ne se répètent pas dans chaque ligne);

Je suis en train d'utiliser la position()

<xsl:template match="c"> 
<tr> 
    <td> 
    <xsl:if test="IT IS THE FIRST C IN A"> 
    <xsl:value-of select="ancestor::A"/> 
    </xsl:if> 
    </td> 
    <td> 
    <xsl:if test="position(1)"> 
    <xsl:value-of select="parent"/> 
    </xsl:if> 
    </td> 
    <td> 
    <xsl:value-of select="."/> 
    </td> 
</tr> 
</xsl:template> 

Il semble que nous devrions imiter la position() pour ancêtre. Existe-t-il une solution générale pour un nombre quelconque de lignes imbriquées?

+0

Pourriez-vous, s'il vous plaît, expliquer mieux? Pourquoi les nœuds commençant à partir de B2 et C3 ne devraient pas apparaître dans la sortie? La règle de production de la sortie n'est pas claire. –

+0

la réponse ci-dessous correspond, merci. L'idée était que tous les nœuds A et B n'apparaissent dans le tableau qu'une seule fois. ne se répète pas. – rudnev

Répondre

2

Vous devez peut-être quelque chose comme ce qui suit (si je comprends bien votre question):

<xsl:template match="C"> 
<tr> 
    <td> 
    <xsl:if test="generate-id(ancestor::A/descendant::C[1]) = generate-id(.)"> 
    <xsl:value-of select="ancestor::A"/> 
    </xsl:if> 
    </td> 
    <td> 
    <xsl:if test="not(previous-sibling::C)"> 
    <xsl:value-of select=".."/> 
    </xsl:if> 
    </td> 
    <td> 
    <xsl:value-of select="."/> 
    </td> 
</tr> 
</xsl:template> 

<xsl:template match="/"> 
    <xsl:apply-templates select="descendant::C"/> 
</xsl:template> 

Edit: vous pouvez également utiliser

not(previous-sibling::C) and not(../previous-sibling::B) 

comme le premier test (au lieu d'utiliser generate-id()) .

+0

Merci beaucoup, ça fonctionne exactement :) – rudnev

Questions connexes