How to COPY same context nodes inside another nodes with xslt - xslt

I trying to group several nodes that have the same contexts inside a existing nodes, by example my case is try to group node Desglose within Detalle, so by example one Node Detalle could have N nodes Desglose.
My Actual XML
<?xml version="1.0" encoding="UTF-8"?>
<MT_Request_Respuesta_plano>
<Cabecera>
<TipoRegistro>C</TipoRegistro>
<TipoFichero>Facturas</TipoFichero>
<CCAA>12</CCAA>
<FechaFichero>20221124</FechaFichero>
<DescripProceso>DESCARGAS DEL FICHERO DE FACTURAS DEL SERMAS </DescripProceso>
<CodigoResultado/>
<DescripResultado/>
<espacios/>
</Cabecera>
<Certificacion>
<TipoRegistro>R</TipoRegistro>
<NroCertificacion>121100</NroCertificacion>
<NombreSPS>SERVICIO MADRILEÑO DE SALUD </NombreSPS>
<DireccionSPS>PLAZA DE CARLOS TRÍAS BERTRÁN, Nº 7, EDIFICIO SOLLUBE </DireccionSPS>
<LocalidadSPS>MADRID </LocalidadSPS>
<CodPostalSPS>28020 </CodPostalSPS>
<FecDesdeLiquidacion>20210316</FecDesdeLiquidacion>
<FecHastaLiquidacion>20210330</FecHastaLiquidacion>
<NroLiquidacionDesde>000000000000000</NroLiquidacionDesde>
<NroLiquidacionHasta>999999999999999</NroLiquidacionHasta>
<TotalLiquidacionesMes>0000075</TotalLiquidacionesMes>
<ImporteTotal>000000001498200</ImporteTotal>
<Observaciones/>
<Libre>914555222 </Libre>
</Certificacion>
<Detalle>
<TipoRegistro>D</TipoRegistro>
<ProvinciaOrigen>28</ProvinciaOrigen>
<CodCentroGrabacion>2803 </CodCentroGrabacion>
<CodCentroAsistencia/>
<NumeroFactura> 2110100556</NumeroFactura>
<ProvinciaDestino>28</ProvinciaDestino>
<FechaGrabacion>20210316</FechaGrabacion>
<Nombre>AURORA </Nombre>
<PrimerApellido>DE </PrimerApellido>
<SegundoApellido>BLAS GUTIERREZ </SegundoApellido>
<NSS>390050482793</NSS>
<IPF>113740356H </IPF>
<IndicadorRecaida>N</IndicadorRecaida>
<FechaAccidente>20171107</FechaAccidente>
<FechaInicioAs>20171107</FechaInicioAs>
<FechaFinAs>20171107</FechaFinAs>
<TipoContingencia>AT</TipoContingencia>
<CodigoContingencia>3</CodigoContingencia>
<espacios/>
</Detalle>
<Desglose>
<TipoRegistro>T</TipoRegistro>
<CodigoPrestaciones>0</CodigoPrestaciones>
<CodConceptoCargo>E03.1.1.2.2.1.1 </CodConceptoCargo>
<FechaTecnica>20171107</FechaTecnica>
<CodHospitalizacion>0</CodHospitalizacion>
<CodTipoTarifa/>
<Unidades>001</Unidades>
<PrecioConcepto>00017500</PrecioConcepto>
<ImporteTotal>0000000017500</ImporteTotal>
<FechaPublicacionBOCA>20170821</FechaPublicacionBOCA>
<espacios/>
</Desglose>
<Desglose>
<TipoRegistro>T</TipoRegistro>
<CodigoPrestaciones>0</CodigoPrestaciones>
<CodConceptoCargo>E03.1.1.2.1.1 </CodConceptoCargo>
<FechaTecnica>20171108</FechaTecnica>
<CodHospitalizacion>0</CodHospitalizacion>
<CodTipoTarifa/>
<Unidades>001</Unidades>
<PrecioConcepto>00011500</PrecioConcepto>
<ImporteTotal>0000000011500</ImporteTotal>
<FechaPublicacionBOCA>20170821</FechaPublicacionBOCA>
<espacios/>
</Desglose>
<Detalle>
<TipoRegistro>D</TipoRegistro>
<ProvinciaOrigen>28</ProvinciaOrigen>
<CodCentroGrabacion>2803 </CodCentroGrabacion>
<CodCentroAsistencia/>
<NumeroFactura> 2110100559</NumeroFactura>
<ProvinciaDestino>28</ProvinciaDestino>
<FechaGrabacion>20210316</FechaGrabacion>
<Nombre>CLAUDIA </Nombre>
<PrimerApellido>JIMENEZ </PrimerApellido>
<SegundoApellido>TORIJA </SegundoApellido>
<NSS>281208193843</NSS>
<IPF>111862836B </IPF>
<IndicadorRecaida>N</IndicadorRecaida>
<FechaAccidente>20171213</FechaAccidente>
<FechaInicioAs>20171213</FechaInicioAs>
<FechaFinAs>20171214</FechaFinAs>
<TipoContingencia>AT</TipoContingencia>
<CodigoContingencia>3</CodigoContingencia>
<espacios/>
</Detalle>
<Desglose>
<TipoRegistro>T</TipoRegistro>
<CodigoPrestaciones>0</CodigoPrestaciones>
<CodConceptoCargo>E03.1.1.2.2.1.1 </CodConceptoCargo>
<FechaTecnica>20171213</FechaTecnica>
<CodHospitalizacion>0</CodHospitalizacion>
<CodTipoTarifa/>
<Unidades>001</Unidades>
<PrecioConcepto>00017500</PrecioConcepto>
<ImporteTotal>0000000017500</ImporteTotal>
<FechaPublicacionBOCA>20170821</FechaPublicacionBOCA>
<espacios/>
</Desglose>
<Detalle>
<TipoRegistro>D</TipoRegistro>
<ProvinciaOrigen>28</ProvinciaOrigen>
<CodCentroGrabacion>2803 </CodCentroGrabacion>
<CodCentroAsistencia/>
<NumeroFactura> 2110100562</NumeroFactura>
<ProvinciaDestino>28</ProvinciaDestino>
<FechaGrabacion>20210316</FechaGrabacion>
<Nombre>SUSANA SARA </Nombre>
<PrimerApellido>MACHO </PrimerApellido>
<SegundoApellido>LOPEZ </SegundoApellido>
<NSS>280343142847</NSS>
<IPF>170164060F </IPF>
<IndicadorRecaida>N</IndicadorRecaida>
<FechaAccidente>20171030</FechaAccidente>
<FechaInicioAs>20171030</FechaInicioAs>
<FechaFinAs>20171031</FechaFinAs>
<TipoContingencia>AT</TipoContingencia>
<CodigoContingencia>3</CodigoContingencia>
<espacios/>
</Detalle>
<Desglose>
<TipoRegistro>T</TipoRegistro>
<CodigoPrestaciones>0</CodigoPrestaciones>
<CodConceptoCargo>E03.1.1.2.2.1.1 </CodConceptoCargo>
<FechaTecnica>20171030</FechaTecnica>
<CodHospitalizacion>0</CodHospitalizacion>
<CodTipoTarifa/>
<Unidades>001</Unidades>
<PrecioConcepto>00017500</PrecioConcepto>
<ImporteTotal>0000000017500</ImporteTotal>
<FechaPublicacionBOCA>20170821</FechaPublicacionBOCA>
<espacios/>
</Desglose>
<Desglose>
<TipoRegistro>T</TipoRegistro>
<CodigoPrestaciones>0</CodigoPrestaciones>
<CodConceptoCargo>E03.1.1.2.1.1 </CodConceptoCargo>
<FechaTecnica>20171102</FechaTecnica>
<CodHospitalizacion>0</CodHospitalizacion>
<CodTipoTarifa/>
<Unidades>001</Unidades>
<PrecioConcepto>00011500</PrecioConcepto>
<ImporteTotal>0000000011500</ImporteTotal>
<FechaPublicacionBOCA>20170821</FechaPublicacionBOCA>
<espacios/>
</Desglose>
<Totales>
<TipoRegistro>X</TipoRegistro>
<TotalRegGrabados>0000184</TotalRegGrabados>
<espacios/>
</Totales>
</MT_Request_Respuesta_plano>
The result I expect is to be able to group the "Desglose" nodes inside the "Detalle" nodes, assuming the sequence in which the "Desglose" nodes arrive to me, after each "Detail" node, could be N "Detalle" with M "Desglose" associated
<?xml version="1.0" encoding="UTF-8"?>
<MT_Request_Respuesta_plano>
<Cabecera>
<TipoRegistro>C</TipoRegistro>
<TipoFichero>Facturas</TipoFichero>
<CCAA>12</CCAA>
<FechaFichero>20221124</FechaFichero>
<DescripProceso>DESCARGAS DEL FICHERO DE FACTURAS DEL SERMA</DescripProceso>
<CodigoResultado/>
<DescripResultado/>
<espacios/>
</Cabecera>
<Certificacion>
<TipoRegistro>R</TipoRegistro>
<NroCertificacion>121100</NroCertificacion>
<NombreSPS>SERVICIO MADRILEÑO DE SALUD </NombreSPS>
<DireccionSPS>PLAZA DE CARLOS TRÍAS BERTRÁN, Nº 7, EDIFICIO SOLLUBE</DireccionSPS>
<LocalidadSPS>MADRID </LocalidadSPS>
<CodPostalSPS>28020 </CodPostalSPS>
<FecDesdeLiquidacion>20210316</FecDesdeLiquidacion>
<FecHastaLiquidacion>20210330</FecHastaLiquidacion>
<NroLiquidacionDesde>000000000000000</NroLiquidacionDesde>
<NroLiquidacionHasta>999999999999999</NroLiquidacionHasta>
<TotalLiquidacionesMes>0000075</TotalLiquidacionesMes>
<ImporteTotal>000000001498200</ImporteTotal>
<Observaciones/>
<Libre>914555222 </Libre>
</Certificacion>
<Detalle>
<TipoRegistro>D</TipoRegistro>
<ProvinciaOrigen>28</ProvinciaOrigen>
<CodCentroGrabacion>2803 </CodCentroGrabacion>
<CodCentroAsistencia/>
<NumeroFactura> 2110100556</NumeroFactura>
<ProvinciaDestino>28</ProvinciaDestino>
<FechaGrabacion>20210316</FechaGrabacion>
<Nombre>AURORA </Nombre>
<PrimerApellido>DE </PrimerApellido>
<SegundoApellido>BLAS GUTIERREZ </SegundoApellido>
<NSS>390050482793</NSS>
<IPF>113740356H </IPF>
<IndicadorRecaida>N</IndicadorRecaida>
<FechaAccidente>20171107</FechaAccidente>
<FechaInicioAs>20171107</FechaInicioAs>
<FechaFinAs>20171107</FechaFinAs>
<TipoContingencia>AT</TipoContingencia>
<CodigoContingencia>3</CodigoContingencia>
<espacios/>
<Desglose>
<TipoRegistro>T</TipoRegistro>
<CodigoPrestaciones>0</CodigoPrestaciones>
<CodConceptoCargo>E03.1.1.2.2.1.1 </CodConceptoCargo>
<FechaTecnica>20171107</FechaTecnica>
<CodHospitalizacion>0</CodHospitalizacion>
<CodTipoTarifa/>
<Unidades>001</Unidades>
<PrecioConcepto>00017500</PrecioConcepto>
<ImporteTotal>0000000017500</ImporteTotal>
<FechaPublicacionBOCA>20170821</FechaPublicacionBOCA>
<espacios/>
</Desglose>
<Desglose>
<TipoRegistro>T</TipoRegistro>
<CodigoPrestaciones>0</CodigoPrestaciones>
<CodConceptoCargo>E03.1.1.2.1.1 </CodConceptoCargo>
<FechaTecnica>20171108</FechaTecnica>
<CodHospitalizacion>0</CodHospitalizacion>
<CodTipoTarifa/>
<Unidades>001</Unidades>
<PrecioConcepto>00011500</PrecioConcepto>
<ImporteTotal>0000000011500</ImporteTotal>
<FechaPublicacionBOCA>20170821</FechaPublicacionBOCA>
<espacios/>
</Desglose>
</Detalle>
<Detalle>
<TipoRegistro>D</TipoRegistro>
<ProvinciaOrigen>28</ProvinciaOrigen>
<CodCentroGrabacion>2803 </CodCentroGrabacion>
<CodCentroAsistencia/>
<NumeroFactura> 2110100559</NumeroFactura>
<ProvinciaDestino>28</ProvinciaDestino>
<FechaGrabacion>20210316</FechaGrabacion>
<Nombre>CLAUDIA </Nombre>
<PrimerApellido>JIMENEZ </PrimerApellido>
<SegundoApellido>TORIJA </SegundoApellido>
<NSS>281208193843</NSS>
<IPF>111862836B </IPF>
<IndicadorRecaida>N</IndicadorRecaida>
<FechaAccidente>20171213</FechaAccidente>
<FechaInicioAs>20171213</FechaInicioAs>
<FechaFinAs>20171214</FechaFinAs>
<TipoContingencia>AT</TipoContingencia>
<CodigoContingencia>3</CodigoContingencia>
<espacios/>
<Desglose>
<TipoRegistro>T</TipoRegistro>
<CodigoPrestaciones>0</CodigoPrestaciones>
<CodConceptoCargo>E03.1.1.2.2.1.1 </CodConceptoCargo>
<FechaTecnica>20171213</FechaTecnica>
<CodHospitalizacion>0</CodHospitalizacion>
<CodTipoTarifa/>
<Unidades>001</Unidades>
<PrecioConcepto>00017500</PrecioConcepto>
<ImporteTotal>0000000017500</ImporteTotal>
<FechaPublicacionBOCA>20170821</FechaPublicacionBOCA>
<espacios/>
</Desglose>
</Detalle>
<Detalle>
<TipoRegistro>D</TipoRegistro>
<ProvinciaOrigen>28</ProvinciaOrigen>
<CodCentroGrabacion>2803 </CodCentroGrabacion>
<CodCentroAsistencia/>
<NumeroFactura> 2110100562</NumeroFactura>
<ProvinciaDestino>28</ProvinciaDestino>
<FechaGrabacion>20210316</FechaGrabacion>
<Nombre>SUSANA SARA </Nombre>
<PrimerApellido>MACHO </PrimerApellido>
<SegundoApellido>LOPEZ </SegundoApellido>
<NSS>280343142847</NSS>
<IPF>170164060F </IPF>
<IndicadorRecaida>N</IndicadorRecaida>
<FechaAccidente>20171030</FechaAccidente>
<FechaInicioAs>20171030</FechaInicioAs>
<FechaFinAs>20171031</FechaFinAs>
<TipoContingencia>AT</TipoContingencia>
<CodigoContingencia>3</CodigoContingencia>
<espacios/>
<Desglose>
<TipoRegistro>T</TipoRegistro>
<CodigoPrestaciones>0</CodigoPrestaciones>
<CodConceptoCargo>E03.1.1.2.2.1.1 </CodConceptoCargo>
<FechaTecnica>20171030</FechaTecnica>
<CodHospitalizacion>0</CodHospitalizacion>
<CodTipoTarifa/>
<Unidades>001</Unidades>
<PrecioConcepto>00017500</PrecioConcepto>
<ImporteTotal>0000000017500</ImporteTotal>
<FechaPublicacionBOCA>20170821</FechaPublicacionBOCA>
<espacios/>
</Desglose>
<Desglose>
<TipoRegistro>T</TipoRegistro>
<CodigoPrestaciones>0</CodigoPrestaciones>
<CodConceptoCargo>E03.1.1.2.1.1 </CodConceptoCargo>
<FechaTecnica>20171102</FechaTecnica>
<CodHospitalizacion>0</CodHospitalizacion>
<CodTipoTarifa/>
<Unidades>001</Unidades>
<PrecioConcepto>00011500</PrecioConcepto>
<ImporteTotal>0000000011500</ImporteTotal>
<FechaPublicacionBOCA>20170821</FechaPublicacionBOCA>
<espacios/>
</Desglose>
</Detalle>
<Totales>
<TipoRegistro>X</TipoRegistro>
<TotalRegGrabados>0000184</TotalRegGrabados>
<espacios/>
</Totales>
</MT_Request_Respuesta_plano>
I've tried this XSLT, one with for-each-group, but no result.
<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="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Detalle">
<xsl:for-each-group select="Detalle | Desglose" group-by="#Detalle">
<Detalle>
<xsl:copy-of select="node()"/>
<xsl:for-each-group select="current-group()" group-by="#Desglose">
<Desglose>
<xsl:for-each select="current-group()">
<xsl:copy-of select="node()"/>
</xsl:for-each>
</Desglose>
</xsl:for-each-group>
</Detalle>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
I also have tried this another XSLT, more nice, but just result with values without label...
<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:key name="Kgrupo" match="Desglose" use="generate-id(preceding-sibling::Detalle[NumeroFactura][1])" />
<xsl:template match="Detalle">
<xsl:copy>
<xsl:for-each select="Desglose">
<xsl:for-each select="key('Kgrupo', generate-id())" >
<Desglose>
<xsl:value-of select="normalize-space(main)" />
</Desglose>
</xsl:for-each>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
I would really appreciate any help to solve this transformation that seems easy, but it is not, at least for me =)

The xsl:for-each-group instruction requires XSLT 2.0 or higher. To do the equivalent of group-starting-with in XSLT 1.0 you need a different method. Your 2nd attempt is close, but it should be:
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="Kgrupo" match="Desglose" use="generate-id(preceding-sibling::Detalle[1])" />
<xsl:template match="/MT_Request_Respuesta_plano">
<xsl:copy>
<xsl:copy-of select="Cabecera | Certificacion"/>
<xsl:for-each select="Detalle">
<xsl:copy>
<xsl:copy-of select="*"/>
<xsl:copy-of select="key('Kgrupo', generate-id())"/>
</xsl:copy>
</xsl:for-each>
<xsl:copy-of select="Totales"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

This XSLT 2.0 answer creates the required output with a recursive named template 'iterate-elements'. The recursive template calls will be 'tail-call-optimised' by an XSLT processor such as Saxon.
I would generally recommend the accepted answer's approach using xsl:for-each and xsl:key as it it simpler and more concise. This alternate approach is a bit more generic however and may be useful if you find the grouping logic becomes more complex later on.
This XSLT template uses 'recursive-sibling` approach to iterate child element of the root element.
Details on the state that is tracked when iterating each element:
$currentElement the current element for each iteration
$targetElement the last previous instance of the Detalle element in the iteration
$sourceElements the Desglose elements following the $targetElement - later injected into $targetElement with the fn:injectElements function
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="com.group-elements.sample"
exclude-result-prefixes="#all"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="#*" mode="#current"/>
<xsl:call-template name="iterate-elements"/>
</xsl:copy>
</xsl:template>
<xsl:template name="iterate-elements">
<xsl:param name="elements" as="element()*" select="*"/>
<xsl:param name="currentElement" select="$elements[1]"/>
<xsl:param name="targetElement" as="element()?" select="()"/>
<xsl:param name="sourceElements" as="element()*"/>
<xsl:choose>
<xsl:when test="empty($currentElement)">
<!-- in case there are any source elements left over: -->
<xsl:sequence select="fn:injectElements($targetElement, $sourceElements)"/>
</xsl:when>
<xsl:when test="fn:isTarget($currentElement)">
<!-- on a new target element so process previous target element and set the new target element -->
<xsl:sequence select="fn:injectElements($targetElement, $sourceElements)"/>
<xsl:call-template name="iterate-elements">
<xsl:with-param name="currentElement" select="$currentElement/following-sibling::*[1]"/>
<xsl:with-param name="sourceElements" select="()"/>
<xsl:with-param name="targetElement" select="$currentElement"/>
</xsl:call-template>
</xsl:when>
<!-- on a new source element so concatanate to the sequence of source elements -->
<xsl:when test="fn:isSource($currentElement)">
<xsl:call-template name="iterate-elements">
<xsl:with-param name="currentElement" select="$currentElement/following-sibling::*[1]"/>
<xsl:with-param name="sourceElements" select="$sourceElements, $currentElement"/>
<xsl:with-param name="targetElement" select="$targetElement"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- not on source/target element - process any target element then emit current element -->
<xsl:sequence select="fn:injectElements($targetElement, $sourceElements), $currentElement"/>
<xsl:call-template name="iterate-elements">
<xsl:with-param name="currentElement" select="$currentElement/following-sibling::*[1]"/>
<xsl:with-param name="sourceElements" select="()"/>
<xsl:with-param name="targetElement" select="()"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:function name="fn:isTarget" as="xs:boolean">
<xsl:param name="element" as="element()"/>
<xsl:sequence select="exists($element[self::Detalle])"/>
</xsl:function>
<xsl:function name="fn:isSource" as="xs:boolean">
<xsl:param name="element" as="element()"/>
<xsl:sequence select="exists($element[self::Desglose])"/>
</xsl:function>
<xsl:function name="fn:injectElements" as="element()?">
<xsl:param name="target" as="element()?"/>
<xsl:param name="sourceElements" as="element()*"/>
<xsl:if test="exists($target)">
<xsl:copy select="$target">
<xsl:copy-of select="$target/#*, $target/node()"/>
<xsl:copy-of select="$sourceElements"/>
</xsl:copy>
</xsl:if>
</xsl:function>
</xsl:stylesheet>[enter link description here][1]

Related

XSLT 3 multi-step transformation

Building from the transformation in this post, I'm now trying to integrate it into a two step transformation where the same node is transformed twice. Tested independent of each other, the transformations work. For reasons I don't understand, when I bring them together using modes, it's not going through the steps correctly - somehow the modes and variables are not aligned correctly? Fiddle here.
Given this XML:
<TEI xmlns="http://www.tei-c.org/ns/1.0" xml:id="MS609-1577">
<teiHeader/>
<text>
<body>
<ab xml:id="MS609-1577-LA" xml:lang="la">
<seg type="dep_event" subtype="sighting" xml:id="MS609-1214-1"><pb break="y" n="80r"/><lb break="y" n="1"/>Item. <date type="deposition_date" when="1245-07-11" xml:id="MS609-1214_depdate">Anno Domini M°CC°XL°V° II° Ydus Junii</date>.
<persName ref="#peire_de_saint-michel" role="dep">P<supplied reason="abbr-name">etrus</supplied> de Sancto Michaele, miles</persName>, testis juratus dixit quod vidit apud
<placeName ref="#laurac_aude" type="sighting_loc">Laurac
<persName ref="#heretics_in_public" role="her">hereticos</persName><lb break="y" n="2"/>publice manentes</placeName>
set nullam familiari<del type="expunctus" rend="after">a</del>tatem habuit cum eis. <date type="sighting_date" when="1225" datingPoint="#MS609-1214_depdate" unit="y" interval="-20">Et sunt XX anni vel circa</date>.</seg>
</ab>
</body>
</text>
</TEI>
My objective is to transform this fragment:
<date type="deposition_date" when="1245-07-11" xml:id="MS609-1214_depdate">Anno Domini M°CC°XL°V° II° Ydus Junii</date>.
Into this ('moving' some text and applying analyze-string to the same node) :
<date type="deposition_date" when="1245-07-11" xml:id="MS609-1214_depdate">Anno Domini M<hi rend="sup">o</hi>CC<hi rend="sup">o</hi>XL<hi rend="sup">o</hi>V<hi rend="sup">o</hi> II<hi rend="sup">o</hi> Ydus Junii.</date>
And the rest copy without changes.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tei="http://www.tei-c.org/ns/1.0"
exclude-result-prefixes="tei"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="no"/>
<xsl:template match="/">
<xsl:variable name="step-one-result">
<xsl:apply-templates select="/" mode="step1"/>
</xsl:variable>
<xsl:apply-templates select="$step-one-result" mode="step2"/>
</xsl:template>
<xsl:template match="text()[contains(.,'°')]" mode="step1">
<xsl:analyze-string select="." regex="°">
<xsl:matching-substring>
<hi xmlns="http://www.tei-c.org/ns/1.0" rend="sup">o</hi>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
<xsl:template match="tei:date[#type='deposition_date' and ./following-sibling::node()[1][. instance of text() and starts-with(.,'.')]]" mode="step2">
<date xmlns="http://www.tei-c.org/ns/1.0">
<xsl:copy-of select="./#*"/>
<xsl:copy-of select="./(* | text())"/>
<xsl:text>.</xsl:text>
</date>
</xsl:template>
<xsl:template match="text()[preceding-sibling::node()[1][./self::tei:date[#type='deposition_date']]][starts-with(.,'.')]" mode="step2">
<xsl:value-of select="substring(.,2)"/>
</xsl:template>
</xsl:stylesheet>
Many thanks in advance.
As you are pushing the whole tree through your modes, I think you forgot to declare
<xsl:mode name="step1" on-no-match="shallow-copy"/>
<xsl:mode name="step2" on-no-match="shallow-copy"/>

XSL transform failing and i can't see why

Being a novice in writing XSL's i'm having issue debugging one for my current project. EditX-XML just fails the transform for errors but doesn't say where they are.
Any advise appreciated
Source XML:
<soa:Label xmlns:soa="urn:telestream.net:soa:core" identifier="ac7af7e5-a536-40ae-b7ca-93e62009c86a" name="Duration - Timecode to Frames" description="" instance="dc07adf4-79e4-4d33-b740-ece5bc0af991" signature="00000000-0000-0000-0000-000000000000">
<soa:Parameter type="timecode" identifier="82795f2a-5a2e-41ca-b1da-0c35a9c584e4" bindable="True" name="Duration Timecode" enabled="true" disableable="false" optionseditable="false" row="-1" column="-1" columnspan="1">00:15:52:10#25
<soa:Default>00:00:00:00#29.97</soa:Default>
<soa:IsRequired>false</soa:IsRequired>
</soa:Parameter>
<soa:Parameter type="int32" identifier="ca643595-6cbb-46b4-bf9b-da93c4348a4e" bindable="True" name="Duration Frames" enabled="true" disableable="false" optionseditable="false" row="-1" column="-1" columnspan="1">0
<soa:Default>0</soa:Default>
<soa:IsRequired>false</soa:IsRequired>
</soa:Parameter>
</soa:Label>
XSL:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soa="urn:telestream.net:soa:core" version="2.0">
<xsl:analyze-string select="/soa:Label/soa:Parameter[1]" regex="^(\d+):(\d+):(\d+):(\d+)#(\d+)$">
<xsl:matching-substring><xsl:variable name="hours" select="xs:integer(regex-group(1))"/>
<xsl:variable name="minutes" select="xs:integer(regex-group(2))"/>
<xsl:variable name="seconds" select="xs:integer(regex-group(3))"/>
<xsl:variable name="frames" select="xs:integer(regex-group(4))"/>
<xsl:variable name="fps" select="xs:integer(regex-group(5))"/>
<xsl:variable name="total-frames" select="$hours * 60 * 60 * $fps + $minutes * 60 * $fps + $seconds * $frames + $frames"/>
</xsl:matching-substring>
</xsl:analyze-string>
<xsl:template match="/">
<soa:Label identifier="5f01d03f-f867-4a57-92e0-19d239a3582d" name="Duration - Timecode to Frames pt2" description="" instance="dc07adf4-79e4-4d33-b740-ece5bc0af991" signature="00000000-0000-0000-0000-000000000000" xmlns:soa="urn:telestream.net:soa:core">
<soa:Parameter type="timecode" identifier="82795f2a-5a2e-41ca-b1da-0c35a9c584e4" bindable="True" name="Duration Timecode" enabled="true" disableable="false" optionseditable="false" row="-1" column="-1" columnspan="1">
<xsl:value-of select="/soa:Label/soa:Parameter[1]"/>
<soa:Default>00:00:00:00#29.97</soa:Default>
<soa:IsRequired>false</soa:IsRequired>
</soa:Parameter>
<soa:Parameter type="int32" identifier="ca643595-6cbb-46b4-bf9b-da93c4348a4e" bindable="True" name="Duration Frames" enabled="true" disableable="false" optionseditable="false" row="-1" column="-1" columnspan="1"><xsl:value-of select="$total-frames"/><soa:Default>0</soa:Default>
<soa:IsRequired>false</soa:IsRequired>
</soa:Parameter>
</soa:Label>
</xsl:template>
</xsl:stylesheet>
Thanks
If you were to test your XSLT at http://xsltransform.net/ you will see there are two errors with your XSLT
Element xsl:analyze-string is not allowed to be a child of
xsl:stylesheet
You have defined a total-frames variable within
this xsl:analyze-string but that means it is only in scope with
the xsl:matching-substring block, so cannot reference it else
where.
See http://xsltransform.net/pPzifqj for specific details
What you need to do is move the xsl:analyze-string but also wrap the xsl:variable declaration of total-frames around it, so that the variable can then be used later on in the template.
Try this XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:soa="urn:telestream.net:soa:core"
version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<soa:Label identifier="5f01d03f-f867-4a57-92e0-19d239a3582d" name="Duration - Timecode to Frames pt2" description="" instance="dc07adf4-79e4-4d33-b740-ece5bc0af991" signature="00000000-0000-0000-0000-000000000000">
<soa:Parameter type="timecode" identifier="82795f2a-5a2e-41ca-b1da-0c35a9c584e4" bindable="True" name="Duration Timecode" enabled="true" disableable="false" optionseditable="false" row="-1" column="-1" columnspan="1">
<xsl:value-of select="normalize-space(/soa:Label/soa:Parameter[1]/text()[1])"/>
<soa:Default>00:00:00:00#29.97</soa:Default>
<soa:IsRequired>false</soa:IsRequired>
</soa:Parameter>
<xsl:variable name="total-frames">
<xsl:analyze-string select="normalize-space(/soa:Label/soa:Parameter[1]/text()[1])"
regex="^(\d+):(\d+):(\d+):(\d+)#(\d+)$">
<xsl:matching-substring>
<xsl:variable name="hours" select="xs:integer(regex-group(1))"/>
<xsl:variable name="minutes" select="xs:integer(regex-group(2))"/>
<xsl:variable name="seconds" select="xs:integer(regex-group(3))"/>
<xsl:variable name="frames" select="xs:integer(regex-group(4))"/>
<xsl:variable name="fps" select="xs:integer(regex-group(5))"/>
<xsl:value-of select="$hours * 60 * 60 * $fps + $minutes * 60 * $fps + $seconds * $frames + $frames"/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:variable>
<soa:Parameter type="int32" identifier="ca643595-6cbb-46b4-bf9b-da93c4348a4e" bindable="True" name="Duration Frames" enabled="true" disableable="false" optionseditable="false" row="-1" column="-1" columnspan="1">
<xsl:value-of select="$total-frames"/>
<soa:Default>0</soa:Default>
<soa:IsRequired>false</soa:IsRequired>
</soa:Parameter>
</soa:Label>
</xsl:template>
</xsl:stylesheet>
Also note where you were selecting soa:Parameter[1] this would have included all line-breaks in the text too, and white-space nodes, so your regular expression would not have matched.
Having said that, it looks like you are are trying to do is append a text value to the second Parameter based on the first one. In that case, you may benefit from using the XSLT identity template.
Try this XSLT too
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:soa="urn:telestream.net:soa:core"
version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="soa:Parameter[2]">
<xsl:copy>
<xsl:apply-templates select="#*"/>
<xsl:analyze-string select="normalize-space(/soa:Label/soa:Parameter[1]/text()[1])"
regex="^(\d+):(\d+):(\d+):(\d+)#(\d+)$">
<xsl:matching-substring>
<xsl:variable name="hours" select="xs:integer(regex-group(1))"/>
<xsl:variable name="minutes" select="xs:integer(regex-group(2))"/>
<xsl:variable name="seconds" select="xs:integer(regex-group(3))"/>
<xsl:variable name="frames" select="xs:integer(regex-group(4))"/>
<xsl:variable name="fps" select="xs:integer(regex-group(5))"/>
<xsl:value-of select="$hours * 60 * 60 * $fps + $minutes * 60 * $fps + $seconds * $frames + $frames"/>
</xsl:matching-substring>
</xsl:analyze-string>
<xsl:apply-templates select="*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

transform XML into one that can be imported into Access

I want to use XSLT to transform XML into one that can be imported into Access the input file is:
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DatosGen>
<Vendedor>
<Nombre>Juan Garcia Sanchez</Nombre>
<Codigo>VE144</Codigo>
</Vendedor>
<Fecha>30-abr-2015</Fecha>
</DatosGen>
<Pedidos>
<Pedido>
<Cabecera>
<Numero>34</Numero>
<Fecha>28-abr-2015</Fecha>
<Cliente>
<Nombre>Antonio Lopez Martin</Nombre>
<Codigo>CL121</Codigo>
</Cliente>
<Portes>SI</Portes>
</Cabecera>
<Detalle>
<Linea>
<Articulo>Ar654</Articulo>
<Cantidad>12</Cantidad>
<Precio>2</Precio>
</Linea>
<Linea>
<Articulo>Ar670</Articulo>
<Cantidad>9</Cantidad>
<Precio>1.21</Precio>
</Linea>
<Linea>
<Articulo>Ar100</Articulo>
<Cantidad>2</Cantidad>
<Precio>3.45</Precio>
</Linea>
<Linea>
<Articulo>Ar999</Articulo>
<Cantidad>215</Cantidad>
<Precio>12.24</Precio>
</Linea>
</Detalle>
</Pedido>
<Pedido>
<Cabecera>
<Numero>35</Numero>
<Fecha>29-abr-2015</Fecha>
<Cliente>
<Nombre>Manuel Enriquez Sousa</Nombre>
<Codigo>CL160</Codigo>
</Cliente>
<Portes>NO</Portes>
</Cabecera>
<Detalle>
<Linea>
<Articulo>Ar003</Articulo>
<Cantidad>10</Cantidad>
<Precio>2.21</Precio>
</Linea>
<Linea>
<Articulo>Ar005</Articulo>
<Cantidad>8</Cantidad>
<Precio>1.28</Precio>
</Linea>
<Linea>
<Articulo>Ar100</Articulo>
<Cantidad>5</Cantidad>
<Precio>3.75</Precio>
</Linea>
</Detalle>
</Pedido>
</Pedidos>
</Document>
Is Output:
<?xml version="1.0" encoding="UTF-8"?>
<dataroot generated="2015-08-22T13:10:05" xmlns:od="urn:schemas-microsoft-com:officedata">
<importarxml>
<Vendedor>Juan Garcia Sanchez</Vendedor>
<idVendedor>VE144</idVendedor>
<FechaFichero>30-abr-2015</FechaFichero>
<Pedido>34</Pedido>
<Fecha>28-abr-2015</Fecha>
<Cliente>Antonio Lopez Martin</Cliente>
<idCliente>CL121</idCliente>
<Portes>SI</Portes>
<Articulo>Ar100</Articulo>
<Cantidad>5</Cantidad>
<Precio>3.75</Precio>
</importarxml>
<importarxml>
<Vendedor>Juan Garcia Sanchez</Vendedor>
<idVendedor>VE144</idVendedor>
<FechaFichero>30-abr-2015</FechaFichero>
<Pedido>34</Pedido>
<Fecha>28-abr-2015</Fecha>
<Cliente>Antonio Lopez Martin</Cliente>
<idCliente>CL121</idCliente>
<Portes>SI</Portes>
<Articulo>Ar005</Articulo>
<Cantidad>8</Cantidad>
<Precio>1.28</Precio>
</importarxml>
<importarxml>
<Vendedor>Juan Garcia Sanchez</Vendedor>
<idVendedor>VE144</idVendedor>
<FechaFichero>30-abr-2015</FechaFichero>
<Pedido>34</Pedido>
<Fecha>28-abr-2015</Fecha>
<Cliente>Antonio Lopez Martin</Cliente>
<idCliente>CL121</idCliente>
<Portes>SI</Portes>
<Articulo>Ar003</Articulo>
<Cantidad>10</Cantidad>
<Precio>2.21</Precio>
</importarxml>
<importarxml>
<Vendedor>Juan Garcia Sanchez</Vendedor>
<idVendedor>VE144</idVendedor>
<FechaFichero>30-abr-2015</FechaFichero>
<Pedido>34</Pedido>
<Fecha>28-abr-2015</Fecha>
<Cliente>Antonio Lopez Martin</Cliente>
<idCliente>CL121</idCliente>
<Portes>SI</Portes>
<Articulo>Ar999</Articulo>
<Cantidad>215</Cantidad>
<Precio>12.24</Precio>
</importarxml>
<importarxml>
<Vendedor>Juan Garcia Sanchez</Vendedor>
<idVendedor>VE144</idVendedor>
<FechaFichero>30-abr-2015</FechaFichero>
<Pedido>35</Pedido>
<Fecha>29-abr-2015</Fecha>
<Cliente>Manuel Enriquez Sousa</Cliente>
<idCliente>CL160</idCliente>
<Portes>No</Portes>
<Articulo>Ar100</Articulo>
<Cantidad>2</Cantidad>
<Precio>3.45</Precio>
</importarxml>
<importarxml>
<Vendedor>Juan Garcia Sanchez</Vendedor>
<idVendedor>VE144</idVendedor>
<FechaFichero>30-abr-2015</FechaFichero>
<Pedido>35</Pedido>
<Fecha>29-abr-2015</Fecha>
<Cliente>Manuel Enriquez Sousa</Cliente>
<idCliente>CL160</idCliente>
<Portes>No</Portes>
<Articulo>Ar670</Articulo>
<Cantidad>9</Cantidad>
<Precio>1.21</Precio>
</importarxml>
<importarxml>
<Vendedor>Juan Garcia Sanchez</Vendedor>
<idVendedor>VE144</idVendedor>
<FechaFichero>30-abr-2015</FechaFichero>
<Pedido>35</Pedido>
<Fecha>29-abr-2015</Fecha>
<Cliente>Manuel Enriquez Sousa</Cliente>
<idCliente>CL160</idCliente>
<Portes>No</Portes>
<Articulo>Ar654</Articulo>
<Cantidad>12</Cantidad>
<Precio>2</Precio>
</importarxml>
</dataroot>
My xslt not work in Pedido Fecha y Cliente:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<dataroot xmlns:od="urn:schemas-microsoft-com:officedata" generated="2015-08-22T13:10:05">
<xsl:for-each select="//Document/Pedidos/Pedido/Detalle/Linea">
<xsl:sort select="//Cliente/Nombre" order="descending" />
<importarxml>
<Vendedor>
<xsl:value-of select="//Vendedor/Nombre" />
</Vendedor>
<idVendedor>
<xsl:value-of select="//Vendedor/Codigo" />
</idVendedor>
<FechaFichero>
<xsl:value-of select="//DatosGen/Fecha" />
</FechaFichero>
<Pedido>
<xsl:value-of select="//Cabecera/Numero" />
</Pedido>
<Fecha>
<xsl:value-of select="//Cabecera/Fecha" />
</Fecha>
<Cliente>
<xsl:value-of select="//Cabecera/Cliente/Nombre" />
</Cliente>
<idCliente>
<xsl:value-of select="//Cabecera/Cliente/Codigo" />
</idCliente>
<Portes>
<xsl:value-of select="//Cabecera/Portes" />
</Portes>
<Articulo>
<xsl:value-of select="Articulo" />
</Articulo>
<Cantidad>
<xsl:value-of select="Cantidad" />
</Cantidad>
<Precio>
<xsl:value-of select="Precio" />
</Precio>
</importarxml>
</xsl:for-each>
</dataroot>
</xsl:template>
</xsl:stylesheet>
You don't have your XPath references correct.
Inside your <xsl:for-each>, all paths are relative to the <Linea> nodes, unless you write absolute paths (paths starting with a /). This is also your main mistake: Absolute paths have no context, therefore they select different nodes than you might want.
To access the vendor name with a relative path it would be required to go up four levels first:
<xsl:value-of select="../../../../DatosGen/Vendedor/Nombre" />
Since this is difficult to follow, it's clearer to use the ancestor axis:
<xsl:value-of select="ancestor::Document[1]/DatosGen/Vendedor/Nombre" />
But of course there is only one <DatosGen> in your input, so you could use absolute paths as well:
<xsl:value-of select="/Document/DatosGen/Vendedor/Nombre" />
Either way, you need that more than once, so you can create and use a variable, like here:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="/Document">
<dataroot xmlns:od="urn:schemas-microsoft-com:officedata" generated="2015-08-22T13:10:05">
<xsl:apply-templates select="Pedidos/Pedido/Detalle/Linea">
<xsl:sort select="Cabecera/Cliente/Nombre" order="descending" />
</xsl:apply-templates>
</dataroot>
</xsl:template>
<xsl:template match="Linea">
<xsl:variable name="DatosGen" select="ancestor::Document[1]/DatosGen" />
<xsl:variable name="Cabecera" select="ancestor::Pedido[1]/Cabecera" />
<importarxml>
<Vendedor><xsl:value-of select="$DatosGen/Vendedor/Nombre" /></Vendedor>
<idVendedor><xsl:value-of select="$DatosGen/Vendedor/Codigo" /></idVendedor>
<FechaFichero><xsl:value-of select="$DatosGen/Fecha" /></FechaFichero>
<Pedido><xsl:value-of select="$Cabecera/Numero" /></Pedido>
<Fecha><xsl:value-of select="$Cabecera/Fecha" /></Fecha>
<Cliente><xsl:value-of select="$Cabecera/Cliente/Nombre" /></Cliente>
<idCliente><xsl:value-of select="$Cabecera/Cliente/Codigo" /></idCliente>
<Portes><xsl:value-of select="$Cabecera/Portes" /></Portes>
<Articulo><xsl:value-of select="Articulo" /></Articulo>
<Cantidad><xsl:value-of select="Cantidad" /></Cantidad>
<Precio><xsl:value-of select="Precio" /></Precio>
</importarxml>
</xsl:template>
</xsl:stylesheet>

How to transform a XML document with metadata using XSLT?

I have a report generator tool that produces XML documents for different kinds of reports. Each of those XML documents will have a set of fields (reporting:columns in the below XML document) which are used to describe the actual data (reporting:line in the below XML document) in it. Since the list of fields is dynamic and keep changing for every kind of report, how to write a generic XSL template that use the 'fields' to transform the data into a csv file.
My sample XML document:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<reporting:root xmlns:reporting="http://www.something.net/reporting">
<reporting:default0 reporting:type="Portfolio">
<reporting:header>
<reporting:configuration>
<reporting:columns>
<reporting:column reporting:group="instrument" reporting:name="Ident" reporting:tag="ident" reporting:type="int"/>
<reporting:column reporting:group="prices" reporting:name="Last (Time)" reporting:tag="lastTime" reporting:type="string"/>
<reporting:column reporting:group="noGroup" reporting:name="RIC" reporting:tag="ric" reporting:type="string"/>
<reporting:column reporting:group="instrument" reporting:name="Reference" reporting:tag="reference" reporting:type="string"/>
<reporting:column reporting:group="result" reporting:name="Currency" reporting:tag="currency" reporting:type="string"/>
</reporting:columns>
</reporting:configuration>
</reporting:header>
<reporting:window reporting:Id="36674" reporting:level="0" reporting:name="MY_PORTFOLIO" reporting:parentId="11991">
<reporting:line reporting:Id="67520135" reporting:level="1" reporting:name="INTERNATIONAL BUSINESS MACHINES CORP" reporting:parentId="36674" reporting:positionType="0">
<reporting:ident>643633</reporting:ident>
<reporting:reference>IBM.USD</reporting:reference>
<reporting:currency>USD</reporting:currency>
</reporting:line>
<reporting:line reporting:Id="67520179" reporting:level="1" reporting:name="GENERAL ELECTRIC CO" reporting:parentId="36674" reporting:positionType="0">
<reporting:ident>643635</reporting:ident>
<reporting:ric>GE.N</reporting:ric>
<reporting:reference>GE.USD</reporting:reference>
<reporting:currency>USD</reporting:currency>
</reporting:line>
</reporting:window>
</reporting:default0>
</reporting:root>
I need to see the output formated like:
ident,lastTime,ric,reference,currency
643633,,,IBM.USD,USD
643635,,GE.N,GE.USD,USD
I did some work on it but it was half way through. Could not find how the handle the 'dynamic' list of fields and use them as tags that describe the actual data.
Can somebody help ?
Thanks.
There are various ways of tackling this in XSLT, but I think the most elegant and maintainable is to write a stylesheet that processes the source document given, and outputs an XSLT stylesheet to do the actual reporting. I've seen this approach used very succesfully in a number of projects.
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each select="/*:root/*:default0/*:header/*:configuration/*:columns/*:column">
<xsl:value-of select="#reporting:tag"/>
<xsl:text>,</xsl:text>
</xsl:for-each>
<xsl:for-each select="/*:root/*:default0/*:window/*:line">
<xsl:variable name="theline" select="."/>
<xsl:text>
</xsl:text>
<xsl:for-each select="/*:root/*:default0/*:header/*:configuration/*:columns/*:column" >
<xsl:variable name="oname" select="#reporting:tag" />
<xsl:value-of select="$theline/*[local-name()=$oname]" /><xsl:text>,</xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
Will produce:
ident,lastTime,ric,reference,currency,
643633,,,IBM.USD,USD,
643635,,GE.N,GE.USD,USD,
( You'll need to stick on a check for last to get rid of the final comma. )
Try
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:r="http://www.something.net/reporting">
<xsl:output method="text" version="1.0"/>
<xsl:template match="/">
<xsl:for-each select="/r:root/r:default0/r:header/r:configuration/r:columns/r:column">
<xsl:value-of select="#r:tag"/>
<xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:for-each select="/r:root/r:default0/r:window/r:line">
<xsl:variable name="POSITION" select="position()"/>
<xsl:for-each select="//r:root/r:default0/r:header/r:configuration/r:columns/r:column">
<xsl:variable name="TAGNAME" select="#r:tag"/><xsl:value-of select="//r:line[$POSITION]/*[local-name()=$TAGNAME]"/><xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Note that I just shortened the namespace prefix to make it easier to read (and type).
This short and simple transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:r="http://www.something.net/reporting">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vColNames" select="/*/*/r:header/*/*/*/#r:tag"/>
<xsl:template match="/">
<xsl:for-each select="$vColNames">
<xsl:value-of select="concat(., ',')"/>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="r:line">
<xsl:variable name="vThis" select="."/>
<xsl:text>
</xsl:text>
<xsl:for-each select="$vColNames">
<xsl:if test="position() > 1">,</xsl:if>
<xsl:apply-templates select="$vThis/*[local-name() = current()]"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
when run on the provided XML document:
<reporting:root xmlns:reporting="http://www.something.net/reporting">
<reporting:default0 reporting:type="Portfolio">
<reporting:header>
<reporting:configuration>
<reporting:columns>
<reporting:column reporting:group="instrument" reporting:name="Ident" reporting:tag="ident" reporting:type="int"/>
<reporting:column reporting:group="prices" reporting:name="Last (Time)" reporting:tag="lastTime" reporting:type="string"/>
<reporting:column reporting:group="noGroup" reporting:name="RIC" reporting:tag="ric" reporting:type="string"/>
<reporting:column reporting:group="instrument" reporting:name="Reference" reporting:tag="reference" reporting:type="string"/>
<reporting:column reporting:group="result" reporting:name="Currency" reporting:tag="currency" reporting:type="string"/>
</reporting:columns>
</reporting:configuration>
</reporting:header>
<reporting:window reporting:Id="36674" reporting:level="0" reporting:name="MY_PORTFOLIO" reporting:parentId="11991">
<reporting:line reporting:Id="67520135" reporting:level="1" reporting:name="INTERNATIONAL BUSINESS MACHINES CORP" reporting:parentId="36674" reporting:positionType="0">
<reporting:ident>643633</reporting:ident>
<reporting:reference>IBM.USD</reporting:reference>
<reporting:currency>USD</reporting:currency>
</reporting:line>
<reporting:line reporting:Id="67520179" reporting:level="1" reporting:name="GENERAL ELECTRIC CO" reporting:parentId="36674" reporting:positionType="0">
<reporting:ident>643635</reporting:ident>
<reporting:ric>GE.N</reporting:ric>
<reporting:reference>GE.USD</reporting:reference>
<reporting:currency>USD</reporting:currency>
</reporting:line>
</reporting:window>
</reporting:default0>
</reporting:root>
produces the wanted, correct result:
ident,lastTime,ric,reference,currency,
643633,,,IBM.USD,USD
643635,,GE.N,GE.USD,USD

how to get value which is above of function for each

I'm stuck to getting data from this xml:
<?xml version="1.0" encoding="UTF-8"?>
<document>
<AAA>Header</AAA>
<BBB>
<CCC>
<DDD>
<EEE>123123</EEE>
<FFF>
<GGG>
<HHH>Body</HHH>
<III>1</III>
</GGG>
<GGG>
<HHH>Body</HHH>
<III>3</III>
</GGG>
</FFF>
</DDD>
</CCC>
<CCC>
<DDD>
<EEE>234234</EEE>
<FFF>
<GGG>
<HHH>Body</HHH>
<III>2</III>
</GGG>
<GGG>
<HHH>Body</HHH>
<III>4</III>
</GGG>
<GGG>
<HHH>Body</HHH>
<III>6</III>
</GGG>
</FFF>
</DDD>
</CCC>
<CCC>
<DDD>
<EEE>345345</EEE>
<FFF>
<GGG>
<HHH>Body</HHH>
<III>7</III>
</GGG>
</FFF>
</DDD>
</CCC>
</BBB>
</document>
Needed result should be:
Header;
Body;1;123123
Body;3;123123
Body;2;234234
Body;4;234234
Body;6;234234
Body;7;345345
My xslt looks:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="text" encoding="Windows-1257" indent="yes"/>
<xsl:template match="/">
<!--Start Header--><xsl:value-of select="document/AAA"/><xsl:text>;</xsl:text>
<!--End Header--><xsl:text>
</xsl:text>
<xsl:for-each select="document/BBB/CCC/DDD/FFF/GGG">
<!--Start Body--><xsl:value-of select="HHH"/><xsl:text>;</xsl:text>
<xsl:value-of select="III"/><xsl:text>;</xsl:text>
<xsl:value-of select="../EEE"/><--This doesn't work-->
<!--End Body--><xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
now I have problem to get value from EEE tag. Please help to solve it because I have no idea how to do it.
From your for-each statement the current context that you are working at is document/BBB/CCC/DDD/FFF/GGG.
The full path of the EEE statement is document/BBB/CCC/DDD/EEE.
Therefore you need to come back two levels to reach the EEE node from the GGG node:
<xsl:value-of select="../../EEE"/>