Merging XML nodes from different parts of a document using XSLT

I am a newbie with XSL Transformations. I tried all possible options in this site from other questions & answers but i think my situation little unique (atleast for me).

I have to parse below xml and construct a key-value pair kinda structure as an output.

My actual xml is as below.

<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema/"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance/" xmlns:HNS="http://tempuri.org/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://tempuri.org/">
<SOAP-ENV:Header>
    <ROClientIDHeader SOAP-ENV:mustUnderstand="0" xmlns="http://tempuri.org/">
        <ID>{E931E54B-DA4C-4A93-9BF3-BF82EE028B26}</ID>
    </ROClientIDHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body xmlns:ro="http://tempuri.org/">
    <v1:Response>
        <v1:Result>
            <v1:Fields>
                <v1:TSimpleDataField>
                    <v1:FieldName>COMMENT</v1:FieldName>
                </v1:TSimpleDataField>
                <v1:TSimpleDataField>
                    <v1:FieldName>SITE_TYPE</v1:FieldName>
                </v1:TSimpleDataField>
                <v1:TSimpleDataField>
                    <v1:FieldName>TOTAL_ADDRESSES</v1:FieldName>
                </v1:TSimpleDataField>
            </v1:Fields>
            <v1:Data>
                <v1:TVarArray>
                    <v1:anyType>DQT NLB Dev</v1:anyType>
                    <v1:anyType>62</v1:anyType>
                    <v1:anyType>100</v1:anyType>
                </v1:TVarArray>
            </v1:Data>
        </v1:Result>
    </v1:Response>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

I want to parse and extract the values under <v1:Fields> and <v1:Data> and construct a single record.

For example, if we take a single key-pair value from these two elements as below

<v1:TSimpleDataField>
    <v1:FieldName>COMMENT</v1:FieldName>
</v1:TSimpleDataField>

And

<v1:TVarArray>
    <v1:anyType>DQT NLB Dev</v1:anyType>

I want to see the output as below

<v1:Response>
  <v1:COMMENT>DQT NLB Dev</v1:COMMENT>
  <v1:SITE_TYPE>62</SITE_TYPE>
  <v1:TOTAL_ADDRESSES>100</v1:TOTAL_ADDRESSES>
</v1:Response>

what is the best way to write the XSLT to extract this data from this given xml. Any help or pointers would be really appreciated.

Upvotes: 1

Views: 109

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117140

Here's an example you could adapt to your needs:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:v1="http://tempuri.org/"
exclude-result-prefixes="SOAP-ENV">

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
    <v1:root>
        <xsl:for-each select="SOAP-ENV:Envelope/SOAP-ENV:Body/v1:Response/v1:Result/v1:Fields/v1:TSimpleDataField">
            <xsl:variable name="i" select="position()" />
            <xsl:element name="v1:{v1:FieldName}">
                <xsl:value-of select="../../v1:Data/v1:TVarArray/v1:anyType[$i]" />
            </xsl:element>
        </xsl:for-each>
    </v1:root>
</xsl:template>     

</xsl:stylesheet>

Applied to your (corrected) example input, the result is:

<?xml version="1.0" encoding="UTF-8"?>
<v1:root xmlns:v1="http://tempuri.org/">
  <v1:COMMENT>DQT NLB Dev</v1:COMMENT>
  <v1:SITE_TYPE>62</v1:SITE_TYPE>
  <v1:TOTAL_ADDRESSES>100</v1:TOTAL_ADDRESSES>
</v1:root>

I repeat here the warning I made in the comments: this will fail if any one of the <v1:FieldName> elements contains a value that cannot be used as a valid XML element name.

Upvotes: 1

Related Questions