Question

I have an XML file with this structure

<projectStructure>
    <projectElements>
        <projectRoles>
            <projectRole>
                <name>Administrators</name>
                <description>A project role that represents administrators in a project</description>
                <defaultGroup>jira-administrators</defaultGroup>
            </projectRole>
            <projectRole>
                <name>Developers</name>
                <description>A project role that represents developers in a project</description>
                <defaultGroup>jira-developers</defaultGroup>
            </projectRole>
        </projectRoles>
        <issueTypes>
            <issueType>
                <name>Action</name>
                <description>A task that needs to be done.</description>
                <subtaskType>false</subtaskType>
                <iconURL>/images/icons/issuetypes/task.png</iconURL>
            </issueType>
            <issueType>
                <name>Bug</name>
                <description>A problem which impairs or prevents the functions of the product.</description>
                <subtaskType>false</subtaskType>
                <iconURL>/images/icons/issuetypes/bug.png</iconURL>
            </issueType>
        </issueTypes>
        <customFields>
            <customField>
                <type>com.atlassian.jira.plugin.system.customfieldtypes:datetime</type>
                <name>Baseline End</name>
                <description>End date of baseline for this issue.</description>
                <searchTemplate>com.atlassian.jira.plugin.system.customfieldtypes:datetimerange</searchTemplate>
            </customField>
            <customField>
                <type>com.atlassian.jira.plugin.system.customfieldtypes:datetime</type>
                <name>Baseline Start</name>
                <description>Start date of baseline for this issue.</description>
                <searchTemplate>com.atlassian.jira.plugin.system.customfieldtypes:datetimerange</searchTemplate>
            </customField>
        </customFields>
    </projectElements>
</projectStructure>

I want to split it in separated XML files for each element inside projectElements. I have managed to extract one element using this xls file with saxon processor (http://www.saxonica.com)

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="issueTypes">
        <xsl:for-each select="issueType">
            <xsl:variable name="elementname" select="name" />
            <xsl:variable name="filename" select="concat('./out/issueType_', $elementname, '.xml')" />
            <xsl:value-of select="$filename" />
            <xsl:result-document exclude-result-prefixes="xs" href="{$filename}">
        <issueType>
    <xsl:copy-of select="node()"/>
        </issueType>
            </xsl:result-document>
        </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Obtaining files issueType_Action.xml, issueType_Bug.xml, etc with a content like

<issueType>
  <name>Action</name>
  <description>A task that needs to be done.</description>
  <subtaskType>false</subtaskType>
  <iconURL>/images/icons/issuetypes/task.png</iconURL>
</issueType>

How can I have two nested loops to iterate the child elements of projectElements (projectRoles, issueTypes and customFields) and for each element iterate in the items to produce issueType_Action.xml, issueType_Bug.xml, customField_BaselineEnd.xml, customField_BaselineStart.xml, etc. ?

All my attempts have failed so far.

Thanks.

Was it helpful?

Solution

Rather than nested for loops, you can apply-templates and use the same template to generate files for the projectRole, issueType, and customField elements:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:template match="/">
        <xsl:apply-templates select="projectStructure/projectElements/*/*"/>
    </xsl:template>

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

    <xsl:template match="projectElements/*/*">
        <xsl:variable name="elementname" select="name" />
        <xsl:variable name="filename" 
            select="concat('./out/', local-name(), '_', $elementname, '.xml')" />

        <xsl:result-document exclude-result-prefixes="xs" href="{$filename}">
            <xsl:copy>
                <xsl:apply-templates/>
            </xsl:copy>
        </xsl:result-document>
    </xsl:template>

</xsl:stylesheet>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top