Patrik
Patrik

Reputation: 88

Nesting some elements into <div> </div> tags using xslt transformation

I'm new in XSLT. I would like to transform xml to html using xslt. I want to add div elements in which will be nested some attributes based on the condition.

I have following xml:

<xml version="1.0" encoding="UTF-8"?>
<ns:form xmlns:ns="http://abcdefghij/datatypes/">
   <ns:sectors>
        <ns:sector>
            <ns:sectorID>Title</ns:sectorID>
            <ns:controls>...</ns:controls>
        </ns:sector>
      <ns:sector>
            <ns:sectorID>Image1</ns:sectorID>
            <ns:controls>...</ns:controls>
        </ns:sector>
      <ns:sector>
            <ns:sectorID>Content1</ns:sectorID>
            <ns:controls>...</ns:controls>
        </ns:sector>
      <ns:sector>
            <ns:sectorID>Links</ns:sectorID>
            <ns:controls>...</ns:controls>
        </ns:sector>
      <ns:sector>
            <ns:sectorID>Buttons</ns:sectorID>
            <ns:controls>...</ns:controls>
        </ns:sector>
   </ns:sectors>
</ns:form>

And I would like to get:

<div id="sablona1" class="override-ckeditor">
   <div id="Title">...</div>
   <div>
      <div id="Image1">...</div>
      <div id="Content1">...</div>
      <div id="Links">...</div>
   </div>
   <div id="Buttons">...</div>
</div>

I have tried this xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://abcdefghij/datatypes/" xmlns:xls="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="ns">
    <xsl:output method="html" />
    <xsl:template match="/ns:form">
        <div id="sablona1" class="override-ckeditor">         
            <xsl:for-each select="ns:sectors/ns:sector">                     

                <!-- starts the code, which is not working -->
                <xsl:choose>
                    <xsl:when test="ns:sectorID = 'Image1'"> 
                        <div>
                    </xsl:when>
                    <xsl:when test="ns:sectorID = 'Buttons'">
                        </div>
                    </xsl:when>
                </xsl:choose>
                <!-- ends the code, which is not working -->

                <div>
                    <xsl:attribute name="id">
                        <xsl:value-of select="ns:sectorID"/>
                    </xsl:attribute>
                    <xsl:apply-templates select="ns:controls"/>
                </div>
            </xsl:for-each>
      </div>
   </xsl:template>
</xsl:stylesheet>

But it returns error:

Unable to generate the XML document using the provided XML/XSL input. org.xml.sax.SAXParseException; lineNumber: 11; columnNumber: 23; The element type "div" must be terminated by the matching end-tag "</div>".

I probably understand what is wrong, but I have no idea how to fix it. Please could you give me some advices? Thanks.

Upvotes: 1

Views: 532

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116992

XSLT is not a word processor. It works with a node tree, not individual tags. And an XSLT stylesheet must be a well-formed XML document, too.

Try perhaps a different approach:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://abcdefghij/datatypes/"
exclude-result-prefixes="ns">
<xsl:output method="html"/>

<xsl:template match="/ns:form">
    <div id="sablona1" class="override-ckeditor"> 
        <div id="Title">
            <xsl:value-of select="ns:sectors/ns:sector[1]/ns:controls"/>
        </div>        
        <div>
            <xsl:for-each select="ns:sectors/ns:sector[position() > 1]">    
                <div id="{ns:sectorID}">
                    <xsl:value-of select="ns:controls"/>
                </div>
            </xsl:for-each>
       </div>
    </div>
</xsl:template>

</xsl:stylesheet>

Or, if you prefer:

<xsl:template match="/ns:form">
    <div id="sablona1" class="override-ckeditor"> 
        <div id="Title">
            <xsl:value-of select="ns:sectors/ns:sector[ns:sectorID = 'Title']/ns:controls"/>
        </div>        
        <div>
            <xsl:for-each select="ns:sectors/ns:sector[ns:sectorID !='Title']">    
                <div id="{ns:sectorID}">
                    <xsl:value-of select="ns:controls"/>
                </div>
            </xsl:for-each>
       </div>
    </div>
</xsl:template>

Upvotes: 1

Related Questions