PoweredByPorkers
PoweredByPorkers

Reputation: 243

XSLT help to split individual nodes into collection of nodes

I have XML that looks like

<?xml version="1.0"?>
<ROWSET>
 <ROW>
  <AAA_ID>43238</AAA_ID>
  <BBB_ID>9</BBB_ID>
  <CCC_COURIER>2</CCC_COURIER>
  <CCC_FAX>33.44</CCC_FAX>
  <CCC_COFFEE>9</CCC_COFFEE>
  <CCC_MARSBARS>3000.43</CCC_MARSBARS>
 </ROW>
 <ROW>
  <AAA_ID>43238</AAA_ID>
  <BBB_ID>10</BBB_ID>
 </ROW>
 <ROW>
  <AAA_ID>43238</AAA_ID>
  <BBB_ID>11</BBB_ID>
 </ROW>
 <ROW>
  <AAA_ID>43238</AAA_ID>
  <BBB_ID>12</BBB_ID>
  <CCC_MISC>5</CCC_MISC>
 </ROW>
</ROWSET>

and I need to modify it so it ends up looking like

<?xml version="1.0"?>
<ROWSET>
 <ROW>
  <AAA_ID>43238</AAA_ID>
  <BBB_ID>9</BBB_ID>
  <CCC>
   <CODE>COURIER</CODE>
   <AMOUNT>2</AMOUNT>
  </CCC>
  <CCC>
   <CODE>FAX</CODE>
   <AMOUNT>33.44</AMOUNT>
  </CCC>
  <CCC>
   <CODE>COFFEE</CODE>
   <AMOUNT>9</AMOUNT>
  </CCC>
  <CCC>
   <CODE>MARSBARS</CODE>
   <AMOUNT>3000.34</AMOUNT>
  </CCC>
 </ROW>
 <ROW>
  <AAA_ID>43238</AAA_ID>
  <BBB_ID>10</BBB_ID>
 </ROW>
 <ROW>
  <AAA_ID>43238</AAA_ID>
  <BBB_ID>11</BBB_ID>
 </ROW>
 <ROW>
  <AAA_ID>43238</AAA_ID>
  <BBB_ID>12</BBB_ID>
  <CCC>
   <CODE>MISC</CODE>
   <AMOUNT>5</AMOUNT>
  </CCC>
 </ROW>
</ROWSET>

Now I have ZERO XSL experience, but I was doing not too badly but my biggest stumbling block is how to split the CCC_???? nodes up into individual nodes and put the ???? code value into it's own node?

Any and all help is most desperately accepted!

Upvotes: 2

Views: 321

Answers (2)

user357812
user357812

Reputation:

This is very direct transformation:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[starts-with(name(),'CCC_')]">
        <CCC>
            <CODE>
                <xsl:value-of select="substring-after(name(),'CCC_')"/>
            </CODE>
            <AMOUNT>
                <xsl:value-of select="."/>
            </AMOUNT>
        </CCC>
    </xsl:template>
</xsl:stylesheet>

Output:

<ROWSET>
    <ROW>
        <AAA_ID>43238</AAA_ID>
        <BBB_ID>9</BBB_ID>
        <CCC>
            <CODE>COURIER</CODE>
            <AMOUNT>2</AMOUNT>
        </CCC>
        <CCC>
            <CODE>FAX</CODE>
            <AMOUNT>33.44</AMOUNT>
        </CCC>
        <CCC>
            <CODE>COFFEE</CODE>
            <AMOUNT>9</AMOUNT>
        </CCC>
        <CCC>
            <CODE>MARSBARS</CODE>
            <AMOUNT>3000.43</AMOUNT>
        </CCC>
    </ROW>
    <ROW>
        <AAA_ID>43238</AAA_ID>
        <BBB_ID>10</BBB_ID>
    </ROW>
    <ROW>
        <AAA_ID>43238</AAA_ID>
        <BBB_ID>11</BBB_ID>
    </ROW>
    <ROW>
        <AAA_ID>43238</AAA_ID>
        <BBB_ID>12</BBB_ID>
        <CCC>
            <CODE>MISC</CODE>
            <AMOUNT>5</AMOUNT>
        </CCC>
    </ROW>
</ROWSET>

Note: Identity rule to copy input as is. Overwriting identity rule for element with name starting with "CCC_".

Upvotes: 3

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 799100

The starts-with() and substring() XPath functions can be used to carve up the node name() into pieces.

Upvotes: 0

Related Questions