3

I'm trying to take my XML document and transform it a different XML structure using XSLT.

Here's my input XML:

<?xml version="1.0" encoding="UTF-8"?>
<ProcessData>
<FTPRemoteHost>RACHEL</FTPRemoteHost>
  <CodeListValues>
    <BCBSRI_FTP_GET>
      <PARM>CD</PARM>
      <VALUE>/Desktop/Rachel</VALUE>
      <DTM/>
    </BCBSRI_FTP_GET>
    <BCBSRI_FTP_GET>
      <PARM>FTPProfileName</PARM>
      <VALUE>1234567890</VALUE>
      <DTM>yyyyMMdd</DTM>
    </BCBSRI_FTP_GET>
    <BCBSRI_FTP_GET>
      <PARM>FileName1</PARM>
      <VALUE>Rachel.txt</VALUE>
      <DTM>yyyyMMdd</DTM>
    </BCBSRI_FTP_GET>
    <BCBSRI_FTP_GET>
      <PARM>MV/DEL</PARM>
      <VALUE>MOVE</VALUE>
      <DTM/>
    </BCBSRI_FTP_GET>
    <BCBSRI_FTP_GET>
      <PARM>SFG_MBX</PARM>
      <VALUE>/inbox/Rachel</VALUE>
      <DTM/>
    </BCBSRI_FTP_GET>
  </CodeListValues>
</ProcessData>

I've tried many different solutions I found here, but I'm unable to get my structure to appear the way I want it to. Here's my XSLT so far:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

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

<xsl:template match="/">
    <resultSet> 
       <xsl:apply-templates select="node() | @*"/>
    </resultSet> 
</xsl:template>

<xsl:template match="/">
    <table>
      <xsl:for-each select="ProcessData/CodeListValues">
        <xsl:for-each select="BCBSRI_FTP_GET">
            <xsl:value-of select="PARM"/>
            <xsl:value-of select="VALUE"/>
            <xsl:value-of select="DTM"/>
        </xsl:for-each>      
      </xsl:for-each>
    </table>
</xsl:template>
</xsl:stylesheet>

I need the output to follow the following pattern:

<CD>/Desktop/Rachel</CD>
<FTPProfileName>1234567890</FTPProfileName>
<DTM>yyyyMMdd</DTM>
<FileName1>Rachel.txt</FileName1>
<DTM>yyyyMMdd</DTM>
<MV/DEL>MOVE</MV/DEL>
<SFG_MBX>/inbox/Rachel</SFG_MBX>

1 Answer 1

2

It looks like you want to create an element with a name specified from the PARM element, containing the value of VALUE. To do this you can use the xsl:element element

<xsl:element name="{PARM}">
    <xsl:value-of select="VALUE"/>
</xsl:element>

However, you won't be able to get the exact result your request because a / is not valid in an element name, and so <MV/DEL> is not a valid XML element. You will need to translate the / into something that is valid, perhaps?

Try this XSLT for starters though (this changes the / to a -)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

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

<xsl:template match="/">
    <table>
      <xsl:for-each select="ProcessData/CodeListValues">
        <xsl:for-each select="BCBSRI_FTP_GET">
            <xsl:element name="{translate(PARM, '/', '-')}">
                <xsl:value-of select="VALUE"/>
            </xsl:element>
            <xsl:copy-of select="DTM[normalize-space()]"/>
        </xsl:for-each>      
      </xsl:for-each>
    </table>
</xsl:template>
</xsl:stylesheet>

Do note that in your XSLT in your question you have two templates matching /. This is considered an error in XSLT, to have two templates matching the same thing with the same priority. XSLT's may either flag the error, or they may ignore all but the last template.

Also note the difference between xsl:copy-of and xsl:value-of. Using xsl:copy-of copies the whole node, whereas xsl:value-of just outputs the string value of it.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.