tags:

views:

79

answers:

2

Hi there,

I have following XML and i want to transform it to my desire XML using XSLT ,i have succeded somewhat but not whole problem is solved .So I need help

Given is My Input XML

<?xml version = '1.0'?>
<ROWSET>
<irp_account num="1">
<IRP_CARRIER_ID_NUMBER>274845</IRP_CARRIER_ID_NUMBER>
<IRP_ACCOUNT_NUMBER>55002</IRP_ACCOUNT_NUMBER>
</irp_account>     
<irp_account num="97">
<IRP_CARRIER_ID_NUMBER>957858</IRP_CARRIER_ID_NUMBER>
<IRP_ACCOUNT_NUMBER>59940</IRP_ACCOUNT_NUMBER>
<NAME_TYPE>LG</NAME_TYPE>
<NAME>SONNY DAVIS INC</NAME>
<ADDRESS_TYPE>MA</ADDRESS_TYPE>
</irp_account>
<irp_account num="98">
<IRP_CARRIER_ID_NUMBER>957858</IRP_CARRIER_ID_NUMBER>
<IRP_ACCOUNT_NUMBER>59940</IRP_ACCOUNT_NUMBER> 
<NAME_TYPE>LG</NAME_TYPE>
<NAME>SONNY DAVIS INC</NAME>
<ADDRESS_TYPE>PH</ADDRESS_TYPE>
</irp_account> 
</ROWSET>

With the use of XSLT i want to generate Output XML like this.

<?xml version="1.0"?> 
<T0020>
<IRP_ACCOUNT>
<IRP_CARRIER_ID_NUMBER>274845</IRP_CARRIER_ID_NUMBER> 
<IRP_ACCOUNT_NUMBER>55002</IRP_ACCOUNT_NUMBER> 
<IRP_NAME>
<NAME_TYPE>LG</NAME_TYPE> 
<NAME>A P SUPPLY CO</NAME> 
<IRP_ADDRESS> 
<ADDRESS_TYPE>PH</ADDRESS_TYPE> 
</IRP_ADDRESS>
<IRP_ADDRESS>
<ADDRESS_TYPE>MA</ADDRESS_TYPE> 
</IRP_ADDRESS>
</IRP_NAME>
</IRP_ACCOUNT>
</T0020>

I have given sample output with only element to save space.

I have tried below XSLT but it is not giving desire result

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
<xsl:template match="/ROWSET"> 
<xsl:element name="T0020">
<xsl:apply-templates select="irp_account"/>
</xsl:element> 
</xsl:template>
<xsl:template match="irp_account">
<xsl:element name="IRP_ACCOUNT">
<xsl:apply-templates select="IRP_CARRIER_ID_NUMBER"/>
<xsl:apply-templates select="IRP_ACCOUNT_NUMBER"/>
<xsl:apply-templates select="IRP_ACCOUNT_TYPE"/>
<xsl:apply-templates select="NAME_TYPE"/> 
<xsl:apply-templates select="ADDRESS_TYPE"/>
</xsl:element> 
</xsl:template>
<xsl:template match="IRP_CARRIER_ID_NUMBER">
<xsl:copy-of select="descendant-or-self::IRP_CARRIER_ID_NUMBER"/>
</xsl:template>
<xsl:template match="IRP_ACCOUNT_NUMBER">
<xsl:copy-of select="descendant-or-self::IRP_ACCOUNT_NUMBER"/>
</xsl:template>
<xsl:template match="IRP_ACCOUNT_TYPE">
<xsl:copy-of select="descendant-or-self::IRP_ACCOUNT_TYPE"/>
</xsl:template>
<xsl:template match="NAME_TYPE"> 
<xsl:element name="IRP_NAME">
<xsl:copy-of select="descendant-or-self::NAME_TYPE"/>
<xsl:copy-of select="following-sibling::NAME"/>
</xsl:element> 
</xsl:template> 
<xsl:template match="ADDRESS_TYPE">
<xsl:element name="IRP_ADDRESS">
<xsl:copy-of select="descendant-or-self::ADDRESS_TYPE"/>
<xsl:copy-of select="following-sibling::NAME"/>
</xsl:element> 
</xsl:template>
</xsl:stylesheet>

Please help

A: 

You're thinking to complicated. Literal elements are output as is - use xsl:element if you need to generate tagnames dynamically. Also note the use of <xsl:copy> to copy verbatim what does not need any changing.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
<xsl:template match="/ROWSET"> 
    <T0020>
        <xsl:apply-templates/>
    </T0020>
</xsl:template>

<xsl:template match="/ROWSET/irp_account"> 
    <IRP_ACCOUNT>
        <xsl:copy-of select="IRP_CARRIER_IP_NUMBER"/>
        <xsl:copy-of select="IRP_ACCOUNT_NUMBER"/>
        <xsl:if test="NAME">
            <IRP_NAME>
                <xsl:copy-of select="NAME"/>
                <xsl:copy-of select="NAME_TYPE"/>
            </IRP_NAME>
        </xsl:if>
        <xsl:if test="ADDRESS_TYPE">
            <IRP_ADDRESS>
                <xsl:copy-of select="ADDRESS_TYPE"/>
            </IRP_ADDRESS>
        </xsl:if>
    </IRP_ACCOUNT>
</xsl:template>
</xsl:stylesheet>

To group multiple items with the same IRP_CARRIER_IP_NUMBER you could do something like:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  <xsl:variable name="accounts" select="/ROWSET/irp_account"/>
  <xsl:template match="/ROWSET"> 
  <T0020>
    <xsl:for-each select="$accounts">
      <xsl:variable name="pos" select="position()"/>
      <xsl:variable name="num" select="./IRP_ACCOUNT_NUMBER/text()"/>
      <xsl:if test="count($accounts[position() &lt; $pos]/IRP_ACCOUNT_NUMBER[text()=$num])=0">
        <xsl:variable name="all-accounts" select="$accounts[IRP_ACCOUNT_NUMBER/text() = $num]"/>
        <IRP_ACCOUNT>
          <xsl:copy-of select="IRP_ACCOUNT_NUMBER"/>
          <xsl:if test="$all-accounts[NAME_TYPE]">
            <IRP_NAME>
              <!-- note: we just take the first name, and don't check 
               if the name is the same for all releated accounts --> 
              <xsl:copy-of select="NAME"/> 
              <!-- note: we just list all name types, and don't check 
               for duplicates --> 
              <xsl:for-each select="$all-accounts">
                <xsl:copy-of select="NAME_TYPE"/> 
              </xsl:for-each>
            </IRP_NAME>
          </xsl:if>
          <xsl:if test="$all-accounts[ADDRESS_TYPE]">
            <IRP_ADDRESS>
              <!-- note: we just list all address types, and don't check 
               for duplicates --> 
              <xsl:for-each select="$all-accounts">
                <xsl:copy-of select="ADDRESS_TYPE"/> 
              </xsl:for-each>
            </IRP_ADDRESS>
          </xsl:if>
        </IRP_ACCOUNT>
      </xsl:if>
    </xsl:for-each>
  </T0020>
</xsl:template>

(don't forget to accept the answer if this was helpful)

Roland Bouman
A: 

Thanks Roland for your answer its very useful me when i transorm using this

<?xml version = '1.0'?>
<ROWSET>
   <irp_account num="97">
      <IRP_CARRIER_ID_NUMBER>957858</IRP_CARRIER_ID_NUMBER>
      <IRP_ACCOUNT_NUMBER>59940</IRP_ACCOUNT_NUMBER>
      <IRP_ACCOUNT_TYPE>I</IRP_ACCOUNT_TYPE>
      <NAME_TYPE>LG</NAME_TYPE>
      <NAME>SONNY DAVIS INC</NAME>
      <ADDRESS_TYPE>MA</ADDRESS_TYPE>
   </irp_account>
   <irp_account num="98">
      <IRP_CARRIER_ID_NUMBER>957858</IRP_CARRIER_ID_NUMBER>
      <IRP_ACCOUNT_NUMBER>59940</IRP_ACCOUNT_NUMBER>
      <IRP_ACCOUNT_TYPE>I</IRP_ACCOUNT_TYPE>
      <NAME_TYPE>LG</NAME_TYPE>
      <NAME>SONNY DAVIS INC</NAME>
      <ADDRESS_TYPE>PH</ADDRESS_TYPE>
   </irp_account>     
</ROWSET>

It has given me following output

<?xml version="1.0" encoding="utf-8" ?> 
<T0020>
 <IRP_ACCOUNT>
    <IRP_ACCOUNT_NUMBER>59940</IRP_ACCOUNT_NUMBER> 
    <IRP_NAME>
        <NAME>SONNY DAVIS INC</NAME> 
        <NAME_TYPE>LG</NAME_TYPE> 
    </IRP_NAME>
    <IRP_ADDRESS>
      <ADDRESS_TYPE>MA</ADDRESS_TYPE> 
    </IRP_ADDRESS>
  </IRP_ACCOUNT>

  <IRP_ACCOUNT>
      <IRP_ACCOUNT_NUMBER>59940</IRP_ACCOUNT_NUMBER> 
      <IRP_NAME>
           <NAME>SONNY DAVIS INC</NAME> 
           <NAME_TYPE>LG</NAME_TYPE> 
      </IRP_NAME>
       <IRP_ADDRESS>
          <ADDRESS_TYPE>PH</ADDRESS_TYPE> 
       </IRP_ADDRESS>
  </IRP_ACCOUNT>
</T0020>

Now is it possible that my output XML come in following format

<?xml version="1.0" encoding="utf-8" ?> 
    <T0020>
     <IRP_ACCOUNT>
        <IRP_ACCOUNT_NUMBER>59940</IRP_ACCOUNT_NUMBER> 
        <IRP_NAME>
            <NAME>SONNY DAVIS INC</NAME> 
            <NAME_TYPE>LG</NAME_TYPE> 
             <IRP_ADDRESS>
                  <ADDRESS_TYPE>MA</ADDRESS_TYPE> 
                  <ADDRESS_TYPE>PH</ADDRESS_TYPE> 
             </IRP_ADDRESS>
        </IRP_NAME>        
      </IRP_ACCOUNT>

    </T0020>

Is it possible that i can group Address Type as other tag's value like (IRP_CARRIER_ID_NUMBER>, ) are same.

Thanks a lot for Wonderful help...

Nisarg Mehta
Ok. So basically, you want to group items with the same IRP_ACCOUNT_NUMBER? Please be more specific in your questions
Roland Bouman
Ok, so I edited my original anwer. Can you please accept it and ask new questions in a separate thread? TIA
Roland Bouman
Ronald,Thanks for your help..its really useful.
Nisarg Mehta