0
votes

I'm trying to transform a XML file with XSLT 1.0 but I'm having troubles with this.

Input:

<task_order>
<Q>
    <record id="1">
        <column name="task_externalId">SPLIT4_0</column>
    </record>
    <record id="2">
        <column name="task_externalId">SPLIT4_1</column>
    </record>    
</Q>
<task>
    <id>SPLIT4</id>
    <name>test</name>
</task>
</task_order>

Wanted result:

For each task_order element: When there is more than 1 record-element (SPLIT4 and SPLIT4_1) I need to duplicate the task element and change the orginal task-id with the id from record elements.

<task_order>
<Q>
    <record id="1">
        <column name="task_externalId">SPLIT4_0</column>
    </record>
    <record id="2">
        <column name="task_externalId">SPLIT4_1</column>
    </record>    
</Q>
<task>
    <id>SPLIT4_0</id>
    <name>test</name>
</task>
<task>
    <id>SPLIT4_1</id>
    <name>test</name>
</task>
</task_order>

Any suggestions?

Thank you

1
I don't get the logic of what you want to achieve. How do you map <task>/<id> in the result? Why, in the first <column> element, SPLIT4_0 is changed to SPLIT_4?potame
Well..it's an interface where the task element (SPLIT4) is delivered but in the other application there are 2 tasks (SPLIT4_0 and SPLIT_1) which needs to be updated with the values from the interface.Jos
Your last statement was an error on my sideJos

1 Answers

0
votes

First start off with the Identity Template which will handle copying across all existing nodes

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

Next, to make looking up the columns slightly easier, consider using an xsl:key

<xsl:key name="column" match="column" use="substring-before(., '_')" />

Then, you have a template matching task where you can look up all matching column elements using the key, and create a new task element for each

<xsl:template match="task">
    <xsl:variable name="task" select="." />
    <xsl:for-each select="key('column', id)">
        <!-- Create new task -->
    </xsl:for-each>
</xsl:template>

Try this XSTL

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:key name="column" match="column" use="substring-before(., '_')" />

    <xsl:template match="task">
        <xsl:variable name="task" select="." />
        <xsl:for-each select="key('column', id)">
            <task>
                <id><xsl:value-of select="." /></id>
                <xsl:apply-templates select="$task/*[not(self::id)]" />
            </task>
        </xsl:for-each>
    </xsl:template>

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