Create elements dynamically in XSLT

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


Create elements dynamically in XSLT



I want to create as many <Group> elements as they are in the Main xml dynamically using XSLT as <Group folder ="Group1"> in the new Xml. Also, the <Data> element added as the last child should be added only once inside.


<Group>


<Group folder ="Group1">


<Data>



Main Xml


<Root>
<ClassA>
<Groups>
<Group1>
<Group2>
<Group3>
............
</Group3>
</Group2>
</Group1>
</Groups>
<Data>
<Name>George</Name>
<Class>A</Class>
</Data>
</ClassA>
</Root>



I need an Xml like this


<Data>
<ClassA>
<Group folder = "Group1">
<Group folder = "Group2">
<Group folder = "Group3">
............

<Data>
<Name>George</Name>
<Class>A</Class>
</Data>
</Group>
</Group>
</Group>

</ClassA>
</Data>




2 Answers
2



Actually, you need the following templates:



Matching Root. Generate <Data> element and inside it
apply templates to the whole own content.


Root


<Data>



Matching ClassA. Copy the own element and inside if
apply templates to the content of the child Groups element.


ClassA


Groups



Matching elements with name containing Group and then a digit.
Create Group element with proper folder attribute.
Apply templates to its content (if any).
If this element does not contain any child element, copy
Data element from ancestor ClassA.


Group


Group


folder


Data


ClassA



The identity template.



So the whole script can look like below:


<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="Root">
<Data><xsl:apply-templates select="@*|node()"/></Data>
</xsl:template>

<xsl:template match="ClassA">
<xsl:copy><xsl:apply-templates select="Groups/*"/></xsl:copy>
</xsl:template>

<xsl:template match="*[matches(name(), 'Groupd')]">
<xsl:element name='Group'>
<xsl:attribute name="folder" select="name()"/>
<xsl:apply-templates select="@*|node()"/>
<xsl:if test="count(*) = 0">
<xsl:copy-of select="ancestor::ClassA/Data"/>
</xsl:if>
</xsl:element>
</xsl:template>

<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
</xsl:transform>



For a working example see http://xsltransform.net/nb9MWtw


<xsl:output method="xml" indent="yes"/>
<xsl:template match="Root">
<xsl:element name="Data">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="ClassA">
<xsl:element name="ClassA">
<group floder="{Groups/Group1/name()}">
<group floder="{Groups/Group1/Group2/name()}">
<group floder="{Groups/Group1/Group2/Group3/name()}">
<xsl:value-of select="Groups/Group1/Group2/Group3"/>
<xsl:copy-of select="Data"/>
</group>
</group>
</group>
</xsl:element>
</xsl:template>



Try if is benifial for you.






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Keycloak server returning user_not_found error when user is already imported with LDAP

PHP parse/syntax errors; and how to solve them?

How to scale/resize CVPixelBufferRef in objective C, iOS