/ / XSLT foreach condición compleja - html, xml, xslt, foreach

XSLT foreach condición compleja - html, xml, xslt, foreach

Quiero transformar el siguiente xml a html usando xslt.

horder - representa la posición de la fila del elemento

vorder - representa la posición de la columna del elemento

filas - número total de filas presentes dentro del elemento

columnas - total no. de columnas presentes dentro del elemento

<Page>
<Sections>
<Section id="parent_hdr_sec" haschild="y" layout="hbox" rows="2" columns="1" horder="1" vorder="1">
<Sections>
<Section id="plan_hdr" layout="vbox" rows="1" columns="6" horder="1" vorder="1" />
<Section id="plan_hdr_dtl" layout="vbox" rows="1" columns="5" horder="2" vorder="1" />
</Sections>
</Section>
<Section id="splitter_sec" haschild="y" layout="vbox" rows="1" columns="2" horder="2" vorder="1">
<Sections>
<Section id="parent_left_sec" haschild="y" layout="hbox" rows="4" columns="1" horder="1" vorder="1" />
<Section id="parent_right_sec" haschild="y" layout="hbox" rows="7" columns="1" horder="1" vorder="2" />
<Section id="parent_left_sec_1" layout="hbox" rows="1" columns="6" horder="2" vorder="1" />
<Section id="parent_right_sec_1" layout="hbox" rows="1" columns="5" horder="2" vorder="2" />
</Sections>
</Section>
</Sections>
</Page>

Necesita salida HTML:

<html>
<body>
<table>
<tr>
<td id="parent_hdr_sec">
<table>
<tr>
<td id="plan_hdr"></td>
</tr>
<tr>
<td id="plan_hdr_dtl"></td>
</tr>
</table>
</td>
</tr>
<tr>
<td id="splitter_sec">
<table>
<tr>
<td id="parent_left_sec"></td>
<td id="parent_right_sec"></td>
</tr>
<tr>
<td id="parent_left_sec_1"></td>
<td id="parent_right_sec_1"></td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>

Por favor ayúdeme a construir XSLT para el anterior ... Necesita sugerencias con respecto a esto ...

Mi XSLT:

 <xsl:template match="/">
<html>
<body>
<table>
<xsl:for-each select="Page/Sections/Section">
<tr>
<td  id="{@id}">

<table>
<xsl:variable name="Rows" select="@rows"/>
<xsl:variable name="Columns" select="@columns"/>
<xsl:variable name="Layout" select="@layout"/>

<xsl:if test="$Layout = "hbox"">
<xsl:for-each select="Sections/Section[$Rows >= position()]">
<tr>
<td id="{@id}">
</td>
</tr>
</xsl:for-each>
</xsl:if>

<xsl:if test="$Layout = "vbox"">
<tr>
<xsl:for-each select="Sections/Section[$Columns >= position()]">
<td id="{@id}">
</td>
</xsl:for-each>
</tr>
</xsl:if>
</table>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>

Usé el XSLT anterior usando la condición foreach y obteniendo una salida como esta

Mi salida:

<?xml version="1.0" encoding="utf-8"?>
<html>
<body>
<table>
<tr>
<td id="parent_hdr_sec">
<table>
<tr>
<td id="plan_hdr" />
</tr>
<tr>
<td id="plan_hdr_dtl" />
</tr>
</table>
</td>
</tr>
<tr>
<td id="splitter_sec">
<table>
<tr>
<td id="parent_left_sec" />
<td id="parent_right_sec" />
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>

Respuestas

2 para la respuesta № 1

A mi me parece otra pregunta de agrupación. Se supone que tanto @horder como @vorder no están clasificados.

@horder en su ejemplo está ordenado, lo que significa que puede deshacerse del bucle interno

Solución XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output omit-xml-declaration="yes" indent="yes"/>


<xsl:template match="//Page">
<html>
<body>
<xsl:apply-templates select="Sections" />
</body>
</html>
</xsl:template>

<xsl:template match="Sections">
<table>
<xsl:for-each-group select="Section" group-by="@vorder">
<xsl:sort select="@vorder"/>
<tr>
<xsl:for-each select="current-group()">
<xsl:sort select="@horder"/>
<xsl:apply-templates select="current()" />
</xsl:for-each>
</tr>
</xsl:for-each-group>
</table>
</xsl:template>

<xsl:template match="Section">
<td>
<xsl:attribute name="id" select="@id" />
<xsl:attribute name="horder" select="@horder" />
<xsl:apply-templates select="Sections" />
</td>
</xsl:template>

</xsl:stylesheet>

XSLT 1.0 Utilicé la agrupación Muenchien, pero tenga en cuenta que @vorder no es único en el conjunto de datos completo, por lo que lo concatené con el identificador de generación del nodo principal.

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

<xsl:key name="section-by-vorder" match="Section" use="concat(generate-id(parent::*), @vorder)" />

<xsl:template match="//Page">
<html>
<body>
<xsl:apply-templates select="Sections" />
</body>
</html>
</xsl:template>

<xsl:template match="Sections">
<table>
<!-- select first Section from each group -->

<xsl:for-each select="Section[count(. | key("section-by-vorder", concat(generate-id(parent::*), @vorder))[1]) = 1]">
<xsl:sort select="@vorder"/>
<tr>
<!-- for all contacts in a group -->
<xsl:for-each select="key("section-by-vorder", concat(generate-id(parent::*), @vorder))">
<xsl:sort select="@horder"/>
<xsl:apply-templates select="current()" />
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</xsl:template>



<xsl:template match="Section">
<td id="{@id} horder={@horder} vorder={@vorder}">
<xsl:apply-templates select="Sections" />
</td>
</xsl:template>

</xsl:stylesheet>