Search code examples
xmlxsltteamsiteinterwoven

Open and close tags dynamically xsl


Im working with teamsite and xsl for generate the output with xsl, Im trying to figure out How to close and open tags dynamically. The problem is: I have a form(teamsite form) with many components, one of those components is a row divider, when this component is added to the form, the output should generate this tag "ContainerType Row2Col1 ContainerType>" and close components and container tag and reopen the tags. This is the way that Im doing it!

RowDivider can be added or not.. it depends the template that the user will use on the page.

with this way... I getting the following error message "Premature end of file", and I know this happens because Im closing and reopens tags on rowdivider section, but I dont know how to resolve it!!

 <Container>
 <ContainerType>Row2Col1</ContainerType>                    
            <Components>
                <xsl:for-each select="content/ContentContainer">
                    <xsl:for-each select="CTA">
                        <Component>
                        <ComponentType>CTA</ComponentType>

                        </Component>
                    </xsl:for-each>
                    <xsl:for-each select="BodyText">
                        <Component>
                            <ComponentType>BodyText</ComponentType>
                            <Attributes>
                                <Attribute>
                                    <Key>HtmlText</Key> 
                                    <Value>
                                        <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
                                        <xsl:value-of select="BodyText" disable-output-escaping="yes"/>
                                        <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
                                    </Value>                            
                                </Attribute>
                            </Attributes>
                        </Component>
                    </xsl:for-each>
                        <xsl:for-each select="RowDivider">
                                </Components>
                                </Container>
                                <Container>
                                <Components>
                        <ContainerType>Row3Col1</ContainerType>
                        </xsl:for-each> 
                </xsl:for-each> 
            </Components>
        </Container>

This should be the output

         <Container>
    <ContainerType>Row2Col1</ContainerType>
    <Components>
        <Component>
            <ComponentType>BodyText</ComponentType>
            <Attributes>
                <Attribute>
                    <Key>HtmlText</Key>
                    <Value>
                        <![CDATA[ <p>Text</p>  ]]>
                    </Value>
                </Attribute>
            </Attributes>
        </Component>
        <Component>
            <ComponentType>CTA</ComponentType>
        </Component>
    </Components>
</Container>
<Container>
    <ContainerType>Row3Col1</ContainerType>
    <Components>
        <Component>
            <ComponentType>BodyText</ComponentType>
            <Attributes>
                <Attribute>
                    <Key>HtmlText</Key>
                    <Value>
                        <![CDATA[ <p>Text</p>  ]]>
                    </Value>
                </Attribute>
            </Attributes>
        </Component>
    </Components>
</Container>

Solution

  • XSLT does not produce tags, it produces a tree. You have to think in terms of producing a tree of nodes as the output of your stylesheet; as an optional step, this result tree can then be serialized to XML.

    Clearly a tree cannot contain half a node; creating a node is an atomic operation.

    I haven't tried to reverse-engineer your requirement from your incorrect attempt at a solution, but the usual problem here is that you want to produce one node in the output document that corresponds to several nodes in the input document. This is generically known as "grouping", and you will find a great deal of information in the XSLT literature once you know that "grouping" is the index term to search on. You should note that grouping problems are much easier to handle in XSLT 2.0 than in 1.0 - but there are plenty of techniques in 1.0 as well.