Search code examples
xmlxslt-1.0

XML and Stylesheet (v1.0): Issue returning multiple values from same record


I have a simple v1.0 stylesheet as below. It needs to be v1.0:

<xsl:stylesheet version = "1.0" xmlns="http://<redacted>" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
    <xsl:output method="xml"/>
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/PFA">
    <data>
        <record skip="true">
            <value name="Id" type="string"/>
            <value name="NameType" type="string"/>
            <value name="Suffix" type="string"/>
            <value name="CarName" type="string"/>
        </record>
        <xsl:apply-templates select="Records/Car"/>
    </data>
</xsl:template>

<xsl:template match="Car">
    <xsl:apply-templates select="NameDetails/Name">
        <xsl:with-param name="id" select="@id"/>
    </xsl:apply-templates>
</xsl:template>

<xsl:template match="Name">
    <xsl:param name="id"/>
    <record>
        <value name="Id">
            <xsl:value-of select="$id"/>
        </value>
        <value name="NameType">
            <xsl:value-of select="@NameType"/>
        </value>
        <value name="Suffix">
            <xsl:value-of select="NameValue/Suffix"/>
        </value>
        <value name="CarName">
            <xsl:value-of select="NameValue/CarName"/>
        </value>
    </record>       
</xsl:template>

</xsl:stylesheet>

I also have an XML file with 1 record that has a number of attributes:

<?xml version="1.0" encoding="UTF-8"?>
    <PFA date="202410281000" type="full">
        <Records>
            <Car id="1023956" action="add" date="26-Feb-2024">
                <NameDetails>
                    <Name NameType="Primary Name">
                        <NameValue>
                            <CarName>Porsche 911 Turbo</CarName>
                        </NameValue>
                    </Name>
                    <Name NameType="Also Known As">
                        <NameValue>
                            <Suffix>Turbo</Suffix>
                            <CarName>Neunelf</CarName>
                        </NameValue>
                        <NameValue>
                            <Suffix>GT1</Suffix>
                            <CarName>Porsche AG 911</CarName>
                        </NameValue>
                    </Name>
                    <Name NameType="Formerly Known As">
                        <NameValue>
                            <Suffix>356</Suffix>
                            <CarName>Porsche</CarName>
                        </NameValue>
                    </Name>
                    <Name NameType="Spelling Variation">
                        <NameValue>
                            <CarName>Porshe 911</CarName>
                        </NameValue>
                        <NameValue>
                            <Suffix>Turbo</Suffix>
                            <CarName>911</CarName>
                        </NameValue>
                    </Name>
                </NameDetails>
            </Car>
        </Records>
    </PFA>

When I read the XML into my third party application it works for the two NameTypes that only have single values (i.e. Primary Name and Formerly Known As).

However, It only renders a single value back for the two NameTypes that have multiple values. In addition, for the Spelling Variation, it appears to pick out the CarName from one NameValue and the Suffix from the other Name Value (i.e. it should keep "911" and "Turbo" together rather than "Porshe 911" and "Turbo".)

What I am getting is this:

enter image description here

But what I was hoping to get was this:

enter image description here

Can anybody help me render my missing rows? Many thanks.


Solution

  • See if this works for you:

    XSLT 1.0

    <xsl:stylesheet version = "1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns="http://redacted">
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="/PFA">
        <data>
            <record skip="true">
                <value name="Id" type="string"/>
                <value name="NameType" type="string"/>
                <value name="Suffix" type="string"/>
                <value name="CarName" type="string"/>
            </record>
            <xsl:for-each select="Records/Car">
                <xsl:variable name="id" select="@id" />
                <xsl:for-each select="NameDetails/Name">
                    <xsl:variable name="nType" select="@NameType" />
                    <xsl:for-each select="NameValue">
                        <record>
                            <value name="Id">
                                <xsl:value-of select="$id"/>
                            </value>
                            <value name="NameType">
                                <xsl:value-of select="$nType"/>
                            </value>
                            <value name="Suffix">
                                <xsl:value-of select="Suffix"/>
                            </value>
                            <value name="CarName">
                                <xsl:value-of select="CarName"/>
                            </value>
                        </record>       
                        </xsl:for-each>
                </xsl:for-each>
            </xsl:for-each>
        </data>
    </xsl:template>
    
    </xsl:stylesheet>