Home > OS >  XSL to create elements based off "header" data
XSL to create elements based off "header" data

Time:09-29

I have the following XML documents:

Doc 1

<root>
<headers>
<heading>Photo</heading>
<heading>Number</heading>
<heading>Month Taken</heading>
<heading>Description</heading>
</headers>
<data>
<item>
<elm1>Cats</elm1>
<elm2>001</elm2>
<elm3>August</elm3>
<elm4>Cats playing in house</elm4>
</item>
<item>
<elm1>Winter</elm1>
<elm2>002</elm2>
<elm3></elm3>
<elm4>Snow covered trees during winter</elm4>
</item>
</data>
</root>

I want to output XML that uses the "headers" piece of the XML to name the elements within the "data," like so.

Ideal output

<data>
<item>
<Photo>Cats</Photo>
<Number>001</Number>
<Month_Taken>August</Month_Taken>
<Description>Cats playing in house</Description>
</item>
<item>
<Photo>Winter</Photo>
<Number>002</Number>
<Month_Taken></Month_Taken>
<Description>Snow covered trees during winter</Description>
</item>
</data>

How would I achieve this? A for loop seems awkward within XSL. I tried to use "position()" but this seemed to have similar issues. Is there an easy way to substitute element names within XSL?

CodePudding user response:

How about:

XSLT 1.0

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

<xsl:template match="/root">
    <data>
        <xsl:variable name="col" select="headers/heading" />
        <xsl:for-each select="data/item">
            <item>
                <xsl:for-each select="*">
                    <xsl:variable name="i" select="position()" />
                    <xsl:element name="{translate($col[$i], ' ', '_')}">
                        <xsl:value-of select="."/>
                    </xsl:element>
                </xsl:for-each>
            </item>
        </xsl:for-each>
    </data>
</xsl:template>

</xsl:stylesheet>   

Do note that merely replacing spaces with underscores does not ensure that the result is a valid element name.

  • Related