Search code examples
xmlxslttransform

XSLT rewrite nested xml elements as one element with a comma seperated value string


I want to transform this all property elements as comma seperated string as one element in xml with xslt

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Products>
<Product>
<productId>1</productId>
<ean>12345</ean>
<title>title A</title>
<Properties>
<Property><key>Colour</key><value>Red</value></Property>
<Property><key>Material</key><value>Plastic</value></Property>
</Properties>
</Product>
<Product>
<productId>2</productId>
<ean>54321</ean>
<title>title B</title>
<Properties>
<Property><key>Colour</key><value>Black</value></Property>
<Property><key>Gender</key><value>Boys</value></Property>
<Property><key>Material</key><value>Leather</value></Property>
</Properties>
</Product>
</Products>

Required output using XSLT

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Products>
<Product>
<productId>1</productId>
<ean>12345</ean>
<title>title A</title>
<Properties><Property>Colour:Red,Material:Plastic</Property></Properties></Product>
<Product>
<productId>2</productId>
<ean>54321</ean>
<title>title B</title>
<Properties><Property>Colour:Black,Gender:Boys,Material:Leather</Property></Properties>
</Product>
</Products>

The result xml as to be flattened without nested structure. If anyone has a better idea to get the propertytypes as elementnames then it would even be better.

If it is possible to get:

<Properties><Colour>Black</Colour><Gender>Boys</Gender><Material>Leather</Material></Properties>

I hope to hear from you!


Solution

  • Please try the following solution.

    Input XML

    <?xml version="1.0"?>
    <Products>
        <Product>
            <productId>1</productId>
            <ean>12345</ean>
            <title>title A</title>
            <Properties>
                <Property>
                    <key>Colour</key>
                    <value>Red</value>
                </Property>
                <Property>
                    <key>Material</key>
                    <value>Plastic</value>
                </Property>
            </Properties>
        </Product>
        <Product>
            <productId>2</productId>
            <ean>54321</ean>
            <title>title B</title>
            <Properties>
                <Property>
                    <key>Colour</key>
                    <value>Black</value>
                </Property>
                <Property>
                    <key>Gender</key>
                    <value>Boys</value>
                </Property>
                <Property>
                    <key>Material</key>
                    <value>Leather</value>
                </Property>
            </Properties>
        </Product>
    </Products>
    

    XSLT

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>
        <xsl:strip-space elements="*"/>
    
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="Property">
            <xsl:element name="{key}">
                <xsl:value-of select="value"/>
            </xsl:element>
        </xsl:template>
    </xsl:stylesheet>
    

    Output XML

    <Products>
      <Product>
        <productId>1</productId>
        <ean>12345</ean>
        <title>title A</title>
        <Properties>
          <Colour>Red</Colour>
          <Material>Plastic</Material>
        </Properties>
      </Product>
      <Product>
        <productId>2</productId>
        <ean>54321</ean>
        <title>title B</title>
        <Properties>
          <Colour>Black</Colour>
          <Gender>Boys</Gender>
          <Material>Leather</Material>
        </Properties>
      </Product>
    </Products>