Search code examples
xmlxml-parsingxslt-2.0

xsl: transforming each tag value


I am creating some performance tests in JMeter and i am trying to make the testscripts as configurable as possible. for instance i use this XML:

<Party>
    <Id>123456</Id>
</Party>
<Agreement>
    <InternalAgreement>
        <Id>2508153801</Id>
        <AgreementType>UYTU</AgreementType>
        <AgreementTypeCombination>ULLL</AgreementTypeCombination>
        <ContractType>3</ContractType>
        <IdCombination>250851536</IdCombination>
        <ProductCode>A260</ProductCode>
    </InternalAgreement>
</Agreement>
<PartyAgreementRole>
    <PartyInternalAgreementRole>
        <PartyAgreementRoleType>AWS</PartyAgreementRoleType>
        <RoleTypeSequenceNumber>054</RoleTypeSequenceNumber>
        <EndDate>2016-11-28</EndDate>
    </PartyInternalAgreementRole>
</PartyAgreementRole>

I want use xslt to transform the above xml to the following (mention the different Id's):

<Party>
    <Id>${Id_1}</Id>
</Party>
<Agreement>
    <InternalAgreement>
        <Id>${Id_2}</Id>
        <AgreementType>${AgreementType}</AgreementType>
        <AgreementTypeCombination>${AgreementTypeCombination}</AgreementTypeCombination>
        <ContractType>${ContractType}</ContractType>
        <IdCombination>${IdCombination}</IdCombination>
        <ProductCode>${ProductCode}</ProductCode>
    </InternalAgreement>
</Agreement>
<PartyAgreementRole>
    <PartyInternalAgreementRole>
        <PartyAgreementRoleType>${PartyAgreementRoleType}</PartyAgreementRoleType>
        <RoleTypeSequenceNumber>${RoleTypeSequenceNumber}</RoleTypeSequenceNumber>
        <EndDate>${EndDate}</EndDate>
    </PartyInternalAgreementRole>
</PartyAgreementRole>

Thus far i have not managed to create a generic solution in xslt that does this. so far i've come up with:

  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="node()/text()[.='VN']">${PartyAgreementRoleType}</xsl:template>

but that's far from the solution. Can somebody direct me in the right direction please?


Solution

  • I don't understand <xsl:template match="node()/text()[.='VN']">${PartyAgreementRoleType}</xsl:template> in your code as there doesn't seem to be any VN in your sample input.

    However, if you want to populate Id elements then

    <xsl:template match="Id">
        <xsl:copy>
            <xsl:text>${Id_</xsl:text>
            <xsl:number level="any"/>
            <xsl:text>}</xsl:text>
        </xsl:copy>
    </xsl:template>
    

    should work and if the other elements are to be populated with their name then

    <xsl:template match="*[not(*)]">
        <xsl:copy>
            <xsl:text>${</xsl:text>
            <xsl:value-of select="local-name()"/>
            <xsl:text>}</xsl:text>
        </xsl:copy>
    </xsl:template>
    

    should achieve that, so taking those templates together you get

    <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="*[not(*)]">
            <xsl:copy>
                <xsl:text>${</xsl:text>
                <xsl:value-of select="local-name()"/>
                <xsl:text>}</xsl:text>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="Id" priority="5">
            <xsl:copy>
                <xsl:text>${Id_</xsl:text>
                <xsl:number level="any"/>
                <xsl:text>}</xsl:text>
            </xsl:copy>
        </xsl:template>
    
    </xsl:transform>
    

    which transforms

    <Root>
    <Party>
        <Id>123456</Id>
    </Party>
    <Agreement>
        <InternalAgreement>
            <Id>2508153801</Id>
            <AgreementType>UYTU</AgreementType>
            <AgreementTypeCombination>ULLL</AgreementTypeCombination>
            <ContractType>3</ContractType>
            <IdCombination>250851536</IdCombination>
            <ProductCode>A260</ProductCode>
        </InternalAgreement>
    </Agreement>
    <PartyAgreementRole>
        <PartyInternalAgreementRole>
            <PartyAgreementRoleType>AWS</PartyAgreementRoleType>
            <RoleTypeSequenceNumber>054</RoleTypeSequenceNumber>
            <EndDate>2016-11-28</EndDate>
        </PartyInternalAgreementRole>
    </PartyAgreementRole>
    </Root>
    

    into

    <?xml version="1.0" encoding="UTF-8"?><Root>
    <Party>
        <Id>${Id_1}</Id>
    </Party>
    <Agreement>
        <InternalAgreement>
            <Id>${Id_2}</Id>
            <AgreementType>${AgreementType}</AgreementType>
            <AgreementTypeCombination>${AgreementTypeCombination}</AgreementTypeCombination>
            <ContractType>${ContractType}</ContractType>
            <IdCombination>${IdCombination}</IdCombination>
            <ProductCode>${ProductCode}</ProductCode>
        </InternalAgreement>
    </Agreement>
    <PartyAgreementRole>
        <PartyInternalAgreementRole>
            <PartyAgreementRoleType>${PartyAgreementRoleType}</PartyAgreementRoleType>
            <RoleTypeSequenceNumber>${RoleTypeSequenceNumber}</RoleTypeSequenceNumber>
            <EndDate>${EndDate}</EndDate>
        </PartyInternalAgreementRole>
    </PartyAgreementRole>
    </Root>
    

    Online at http://xsltransform.net/naZXpWR/1.