Transform XML to HTML using XSLT

Hello, I need help transforming an XML document to HTML.

This is a sample of my XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<impuesto>
	<titulo>Renta del Pequeño Contribuyente</titulo>
	<ley_articulo>
		<titulo>Ley 2421/04</titulo>
		
		<contenido>
			<p>Concordada con los Decretos Nº 8.593/06 , decreto 5610/10 y la Res. Nº 44/10 Art. con su anexo A y B</p>
			
			<p><strong>Definiciones y Conceptos</strong></p>
			
			<decreto>
				<titulo>Decreto Nº 8.593/06</titulo>
				<contenido>
					<p><strong>Artículo 1º - Conceptos</strong> Para la aplicación del Impuesto a la Renta del Pequeño Contribuyente se tendrán en cuenta los conceptos, 	definiciones y aclaraciones indicadas en este artículo:</p>

					<p><strong>a) Administración o Administración Tributaria:</strong> La Subsecretaría de Estado de Tributación del Ministerio de Hacienda, creada por Ley Nº 109/91 y sus modificaciones.</p>

					<p><strong>b) Cese o clausura de actividades o cierre definitivo de negocios:</strong> Proceso formal mediante el cual concluyen definitivamente las actividades económicas de un Contribuyente afectadas al presente Impuesto. Este concepto no incluye a la "clausura" como sanción, establecida por el Artículo 174 de la ley; tampoco incluye la suspensión temporal de actividades del negocio, entendiéndose temporal hasta que se presente a la Administración Tributaria la Declaración Jurada de Cierre a que se refiere el Artículo 14 "Cese o Clausura de Actividades" de este Decreto.</p>
				</contenido>
			</decreto>
		
			<decreto>
				<titulo>Decreto Nº 5.697/10</titulo>
				<contenido>
					<p>Modificase el literal c) del Artículo 1º del Decreto Nº 8593/2006, el cual queda redactado de la siguiente manera:</p>

					<p><strong>c) Comprobante de Venta:</strong> Documento autorizado por la Administración Tributaria  para respaldar actos de compra, venta, contrataciones y prestaciones de servicios. Su timbrado, uso y documentos complementarios se rigen por el Decreto Nº 6539/2005 y sus normas modificatorias y complementarias".</p>

					<p><strong>d) Empresa Unipersonal:</strong> Toda unidad productiva perteneciente a una persona física, en la que se utilice en forma conjunta el capital y el trabajo, propios o ajenos, en cualquier proporción, con el objeto de obtener un resultado económico, con excepción de los servicios de carácter personal.</p>

					<p>A los fines del Impuesto, las empresas individuales de responsabilidad limitada, los condominios de personas físicas y las sucesiones indivisas son consideradas empresas unipersonales.</p>

					<p><strong>e) Impuesto o IRPC:</strong> Impuesto a la Renta del Pequeño Contribuyente.</p>

					<p><strong>f) Ley:</strong> La Ley Nº 125/91, con sus modificaciones.</p>

					<p><strong>g) Servicio de carácter personal:</strong> Aquel para cuya realización es preponderante la utilización del factor trabajo.</p>

					<p><strong>h) Servicio no personal:</strong> Aquel para cuya realización es necesaria la utilización conjunta del capital y del trabajo en cualquier proporción o aquél en cuya realización se utiliza de forma exclusiva el factor capital.</p>
				</contenido>
			</decreto>
		
			<resolucion>
				<titulo>Resolución Nº 1560/06</titulo>
				<contenido>
					<p><strong>Artículo 1º - Conceptos</strong>  Para la aplicación de la presente Resolución se tendrán en cuenta los conceptos, definiciones y aclaraciones indicadas en este artículo:</p>

					<p><strong>a) Administración o Administración Tributaria:</strong> La Subsecretaria de Estado de Tributación del Ministerio de Hacienda, creada por Ley Nº 109/91 y sus modificaciones.</p>
					<p><strong>b) Impuesto o IRPC:</strong> Impuesto a la Renta del Pequeño Contribuyente.</p>
					<p><strong>c) Ley:</strong> La Ley Nº 125/91, con sus modificaciones. </p>
					<p><strong>d) Decreto:</strong> El Decreto Nº 8593 de fecha 11 de diciembre de 2006.</p>
					<p><strong>e) IRACIS:</strong> Impuesto a la Renta Comercial, Industrial o de Servicios.</p>
					<p><strong>f) IVA:</strong> Impuesto al Valor Agregado</p>
				</contenido>
			</resolucion>

			<resolucion>
				<titulo>Resolución Nº 44/10Art.  1º.-</titulo>
				<contenido>
					<p>Modifícase el literal g) del Artículo 1º de la Resolución Nº 1560/06, que quedará redactado del siguiente modo:</p>

					<p><strong>g) Comprobantes:</strong> Las facturas, Boletas de Ventas, Tickets, Autofacturas y demás documentos previstos en el Decreto N° 6539/05 y sus normas modificatorias y  complementarias.".</p>
				</contenido>
			</resolucion>
			
		</contenido>
	</ley_articulo>		
	
	<ley_articulo>
		<titulo>Artículo 42 - Primer Párrafo</titulo>
		<contenido>
			<p><strong>Hecho Generador:</strong> El Impuesto a la Renta del Pequeño Contribuyente Gravará los ingresos provenientes de la realización de actividades comerciales, industriales o de servicio que no sean de carácter personal.</p>

			<decreto>
				<titulo>Decreto Nº 8.593/06</titulo>
				<contenido>
					<p>Artículo 2º - Objeto: El Impuesto grava los ingresos de fuente paraguaya provenientes de la realización de actividades comerciales, industriales o de servicios que no sean de carácter personal, obtenidos por los sujetos pasivos definidos en el Artículo 3º del presente Reglamento.</p>
				</contenido>
			</decreto>
		</contenido>
	</ley_articulo>
</impuesto>

Open in new window


I'm using this XSLT to transform it to HTML:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />

	<xsl:template match="/"> 
		
		<xsl:for-each select="impuesto/ley_articulo">
			<xsl:variable name="x" select="position()" />
			<div id="ley_articulo{$x}">
				<div class="panel panel-primary">
					<div class="panel-heading">
						<h4 class="panel-title"><xsl:value-of select="titulo"/></h4>
					</div>
				</div>

				<xsl:if test="contenido/decreto">
					<xsl:for-each select="contenido/decreto">
						<xsl:variable name="y" select="position()" />
						<div class="panel-group" id="accordion">
							<div class="panel panel-success">
								<div class="panel-heading">
									<h4 class="panel-title">
										<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" href="#decreto{$x}_{$y}">
											<xsl:value-of select="titulo"/>
										</a>
									</h4>
								</div>
								<div id="decreto{$x}_{$y}" class="panel-collapse collapse">
									<div class="panel-body">
										<xsl:copy-of select="contenido"/>
									</div>
								</div>
							</div>
						</div>
					</xsl:for-each>
				</xsl:if>

				<xsl:if test="contenido/resolucion">
					<xsl:for-each select="contenido/resolucion">
						<xsl:variable name="z" select="position()" />
						<div class="panel-group" id="accordion">
							<div class="panel panel-info">
								<div class="panel-heading">
									<h4 class="panel-title">
										<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" href="#resolucion{$x}_{$z}">
											<xsl:value-of select="titulo"/>
										</a>
									</h4>
								</div>
								<div id="resolucion{$x}_{$z}" class="panel-collapse collapse">
									<div class="panel-body">
										<xsl:copy-of select="contenido"/>
									</div>
								</div>
							</div>
						</div>
					</xsl:for-each>
				</xsl:if>
				
				<xsl:if test="contenido/p">
					<xsl:for-each select="contenido/p">
						<xsl:copy-of select="." />
					</xsl:for-each>
				</xsl:if>

			</div>
		</xsl:for-each>
				
	</xsl:template>
	
</xsl:stylesheet>

Open in new window


Now I have all the elements, but not in the correct order. First all the "decreto" appear, then all the "resolucion" and finally all the text inside "ley_articulo/contenido" that's not a "decreto" nor a "resolucion".

How can I make them appear all of them in their original places? Thanks.
LVL 1
ivanblueAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Geert BormansInformation ArchitectCommented:
You should not use for-each for walking a tree this way. If you would use apply-templates instead, your code becomes much leaner, and easier to control

untested:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
    
    <xsl:template match="/"> 
        <xsl:apply-templates select="impuesto/ley_articulo"></xsl:apply-templates>
     </xsl:template>

    <xsl:template match="impuesto/ley_articulo">
        <xsl:variable name="x" select="position()" />
        <div id="ley_articulo{$x}">
            <div class="panel panel-primary">
                <div class="panel-heading">
                    <h4 class="panel-title"><xsl:value-of select="titulo"/></h4>
                </div>
            </div>
            <xsl:apply-templates select="contenido/decreto | contenido/resolucion | contenido/p"/>
        </div>
        
    </xsl:template>
    
    <xsl:template match="contenido/decreto">
        <xsl:variable name="y" select="position()" />
        <xsl:variable name="x" select="count(parent::contenido/parent::ley_articulo/preceding-sibling::ley_articulo) + 1" />
        <div class="panel-group" id="accordion">
            <div class="panel panel-success">
                <div class="panel-heading">
                    <h4 class="panel-title">
                        <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" href="#decreto{$x}_{$y}">
                            <xsl:value-of select="titulo"/>
                        </a>
                    </h4>
                </div>
                <div id="decreto{$x}_{$y}" class="panel-collapse collapse">
                    <div class="panel-body">
                        <xsl:copy-of select="contenido"/>
                    </div>
                </div>
            </div>
        </div>
    </xsl:template>
    
    <xsl:template match="contenido/resolucion">
        <xsl:variable name="z" select="position()" />
        <xsl:variable name="x" select="count(parent::contenido/parent::ley_articulo/preceding-sibling::ley_articulo) + 1" />
        <div class="panel-group" id="accordion">
            <div class="panel panel-info">
                <div class="panel-heading">
                    <h4 class="panel-title">
                        <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" href="#resolucion{$x}_{$z}">
                            <xsl:value-of select="titulo"/>
                        </a>
                    </h4>
                </div>
                <div id="resolucion{$x}_{$z}" class="panel-collapse collapse">
                    <div class="panel-body">
                        <xsl:copy-of select="contenido"/>
                    </div>
                </div>
            </div>
        </div>
    </xsl:template>
    
    <xsl:template match="contenido/p">
        <xsl:copy-of select="." />
    </xsl:template>
        
    
</xsl:stylesheet>

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ivanblueAuthor Commented:
Wow! I'm amazed! I didn't use templates because I didn't understand them. Now I can see better how they work.

Your code work perfectly! Thank you so much! :D
0
Geert BormansInformation ArchitectCommented:
welcome

you need to see templates as an independent piece of code that do something with nodes that match the pattern in the match attribute

apply-templates push nodes to the templates... the most specific match wins

this mechanism is often not clearly understood by programmers that have a procedural background. Hence a lot of programmers only have one template and wrap everything inside for-each statements... leading to code that is hard to understand

I try to avoid for-each in my code. Most of the times it can be rewritten using apply-templates. Try to learn to adapt that programming style. You will thank me for pushing you in that direction once you come to the point of having to change old stylesheets :-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
XML

From novice to tech pro — start learning today.