Home > Software design >  Move the selected nodes to different node and remove selected elements
Move the selected nodes to different node and remove selected elements

Time:04-07

I'm trying to move the nodes and remove the array element fields. In the below XML there are multiple occurences of phoneVoice and Addresses field, iam trying to make these elements as root and inside node as array. Below is the request xml

<rsp:response xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rsp="rsp.com/employee/Response/v30"
xmlns:res="res.com/Member/details/v1"
xmlns:resp="resp.com/details/v1">
<res:employee>
    <resp:Employee>
        <resp:FirstName>abc</resp:FirstName>
        <resp:middleName></resp:middleName>
        <resp:details>
            <resp:Details>
                <resp:type>postal</resp:type>  
                <resp:phonesVoice>
                    <resp:Phone>
                        <resp:textLabel>LIFELINE</resp:textLabel>
                        <resp:number/>
                    </resp:Phone>
                </resp:phonesVoice>
                <resp:phonesVoice>
                    <resp:Phone>
                        <resp:textLabel>Intl</resp:textLabel>
                        <resp:number/>
                    </resp:Phone>
                </resp:phonesVoice>
                <resp:Addresses>
                    <resp:Address>
                        <resp:country>XYZ</resp:country>
                    </resp:Address>
                </resp:Addresses>
            </resp:Details>
            <resp:Details>
                <resp:type>ofc</resp:type> 
                <resp:Addresses>
                    <resp:Address>
                        <resp:country>XYZ</resp:country>
                    </resp:Address>
                </resp:Addresses>
            </resp:Details>
        </resp:details>
    </resp:Employee>
</res:employee>

</rsp:response>

Below is the XSLT used to achieve the result.

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:resp="resp.com/details/v1">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="resp:details">
    <xsl:copy>
        <Details>
            <xsl:apply-templates select="@*|resp:Details/*"/>
        </Details>
    </xsl:copy>
</xsl:template>


<xsl:template match="resp:Address">
    <xsl:copy>
        <xsl:apply-templates/>
        <xsl:copy-of select="../../resp:type"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="resp:type"/>

</xsl:stylesheet>

Below is the output of the XSLT(partially achieved)

    <?xml version="1.0" encoding="UTF-8"?>
<rsp:response xmlns:xs="http://www.w3.org/2001/XMLSchema"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:rsp="rsp.com/employee/Response/v30"
              xmlns:res="res.com/Member/details/v1"
              xmlns:resp="resp.com/details/v1">
   <res:employee>
      <resp:Employee>
         <resp:FirstName>abc</resp:FirstName>
         <resp:middleName/>
         <resp:details>
            <Details>
               <resp:phonesVoice>
                  <resp:Phone>
                     <resp:textLabel>LIFELINE</resp:textLabel>
                     <resp:number/>
                  </resp:Phone>
               </resp:phonesVoice>
               <resp:phonesVoice>
                  <resp:Phone>
                     <resp:textLabel>Intl</resp:textLabel>
                     <resp:number/>
                  </resp:Phone>
               </resp:phonesVoice>
               <resp:Addresses>
                  <resp:Address>
                     <resp:country>XYZ</resp:country>
                     <resp:type>postal</resp:type>
                  </resp:Address>
               </resp:Addresses>
               <resp:Addresses>
                  <resp:Address>
                     <resp:country>XYZ</resp:country>
                     <resp:type>ofc</resp:type>
                  </resp:Address>
               </resp:Addresses>
            </Details>
         </resp:details>
      </resp:Employee>
   </res:employee>
</rsp:response>

Below is the desired output

    <?xml version="1.0" encoding="UTF-8"?>
<rsp:response xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:rsp="rsp.com/employee/Response/v30"
    xmlns:res="res.com/Member/details/v1"
    xmlns:resp="resp.com/details/v1">
    <res:employee>
        <resp:Employee>
            <resp:FirstName>abc</resp:FirstName>
            <resp:middleName/>
            <resp:details>
                <Details>
                    <resp:phonesVoice>
                        <resp:Phone>
                            <resp:textLabel>LIFELINE</resp:textLabel>
                            <resp:number/>
                        </resp:Phone>
                        <resp:Phone>
                            <resp:textLabel>Intl</resp:textLabel>
                            <resp:number/>
                        </resp:Phone>
                    </resp:phonesVoice>
                    <resp:Addresses>
                        <resp:Address>
                            <resp:country>XYZ</resp:country>
                            <resp:type>postal</resp:type>
                        </resp:Address>
                        <resp:Address>
                            <resp:country>XYZ</resp:country>
                            <resp:type>ofc</resp:type>
                        </resp:Address>
                    </resp:Addresses>
                </Details>
            </resp:details>
        </resp:Employee>
    </res:employee>
</rsp:response>

CodePudding user response:

AFAICT you want to do:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:resp="resp.com/details/v1">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="resp:details">
    <xsl:variable name="phones" select="resp:Details/resp:phonesVoice" />
    <xsl:variable name="addr" select="resp:Details/resp:Addresses" />
    <xsl:copy>
        <Details>
            <xsl:if test="$phones">
                <resp:phonesVoice>
                    <xsl:copy-of select="$phones/resp:Phone"/>
                </resp:phonesVoice>
            </xsl:if>
            <xsl:if test="$addr">
                <resp:Addresses>
                    <xsl:apply-templates select="$addr/resp:Address"/>
                </resp:Addresses>
            </xsl:if>
        </Details>
    </xsl:copy>    
</xsl:template>

<xsl:template match="resp:Address">
    <xsl:copy>
        <xsl:copy-of select="resp:country"/>
        <xsl:copy-of select="../../resp:type"/>
    </xsl:copy>    
</xsl:template>

</xsl:stylesheet> 
  • Related