user5988576
user5988576

Reputation:

Use XSLT 1.0 to regroup nodes

I seem to be having a problem in reformatting several xml files into groupings that are more ingestible for other tools I'm working with...

Also, I'm restricted to using XSLT 1.0 for this problem.

Here is a sample-style of how my input XML files are organized in folder "C:/SampleFolder":

<data>
   <PersonID>12345</PersonID>
   <PersonName>Gary Johnson</PersonName>
   <PersonDetails>
      <CurrAcct status="Y">
         <LastUpdated>26 FEB 2016</LastUpdated>
         <Comments>THIS IS AN INTERESTING COMMENT</Comments>
      </CurrAcct>
      <Threshold status="Y">
         <LastUpdated>01 FEB 2016</LastUpdated>
         <Comments>Blah Blah Blah</Comments>
      </Threshold>
   </PersonDetails>
</data>

And here is how I would like it to look:

<data>
   <PersonID>12345</PersonID>
   <PersonName>Gary Johnson</PersonName>
   <PersonDetails>
      <CurAcct>Y</CurrAcct>
      <CurrAcctLastUpdated>26 FEB 2016</CurrAcctLastUpdated>
      <CurrAcctComments>THIS IS AN INTERESTING COMMENT</CurrAcctComments>
      <Threshold>Y</Threshold>
      <ThresholdLastUpdated>01 FEB 2016</ThresholdLastUpdated>
      <ThresholdComments>Blah Blah Blah</ThresholdComments>
   </PersonDetails>
</data>

So essentially what I would like to do is three things (in order of precedence):

  1. I would like to be able to regroup the nodes to all fall directly under "PersonDetails"

  2. Uniquely rename the former subnodes so that they don't all cram into one field when exporting data in the xml into tables.

  3. I would like to be able to somehow batch process all of them at once... I have tried to work on this problem first, but can't seem to find anything that will let me do this effectively (ie: using wildcards to pick up all the xmls in the folder) in XLST 1.0, as the collection() function is not available.

Additional Note:

-In reality, the xml files are much larger with many more details, ultimately I would be just nugging-out the specific reformat criteria for each different grouping. Unless you all think that this is an utterly stupid idea, in which case- I'm always open to learning something new.

Alright, I think that's it. I've really run into a brick wall with this one, so thank you ahead of time everybody...

Upvotes: 0

Views: 105

Answers (1)

zx485
zx485

Reputation: 29022

One possibility to achieve this is the following XSLT template:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
  <xsl:template match="/data">
    <data>
        <xsl:copy-of select="*[local-name() != 'PersonDetails']" />
        <PersonDetails>
            <xsl:apply-templates select="PersonDetails" />
        </PersonDetails>
    </data>
  </xsl:template>

  <xsl:template match="CurrAcct | Threshold">
    <xsl:variable name="cur" select="local-name()" />
    <xsl:element name="{$cur}">
        <xsl:value-of select="@status" />
    </xsl:element>
    <xsl:for-each select="*">
        <xsl:element name="{concat($cur,local-name())}">
            <xsl:value-of select="text()" />
        </xsl:element>
    </xsl:for-each>
  </xsl:template> 
</xsl:stylesheet> 

The result is

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <PersonID>12345</PersonID>
    <PersonName>Gary Johnson</PersonName>
    <PersonDetails>
        <CurrAcct>Y</CurrAcct>
        <CurrAcctLastUpdated>26 FEB 2016</CurrAcctLastUpdated>
        <CurrAcctComments>THIS IS AN INTERESTING COMMENT</CurrAcctComments>
        <Threshold>Y</Threshold>
        <ThresholdLastUpdated>01 FEB 2016</ThresholdLastUpdated>
        <ThresholdComments>Blah Blah Blah</ThresholdComments>
    </PersonDetails>
</data>

Upvotes: 1

Related Questions