abhishek bisht
abhishek bisht

Reputation: 33

Transforming Xml using XSLT 1.0

I have a requirement where i nedd totransform my xml.

This is the xml given to me

<InvoiceDocument>
<Invoice>
<d>100</d>
<a>120</a>
<Products>
<Product>
<b>11<b>
<c>12</c>
</Product>
<Product>
<b>13</b>
<c>14</c>
</Product>
</Products>
</Invoice>
</InvoiceDocument>

This the xml that i require is

<MessageParts>
<LedgerJournalTable class="entity>
<z>50</z>
<LedgerJournalTrans class="entity'>
<e>120</e>
</LedgerJournalTrans>
<LedgerJournalTrans class="entity'>
<g>11</g>
<h>12</h>
</LedgerJournalTrans>
<LedgerJournalTrans class="entity'>
<g>13</g>
<h>14</h>
</LedgerJournalTrans>
</LedgerJournalTable>
</MessageParts>

I tried to use this code for transforming my xml but was not bale to transform it

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="InvoiceDocument">
    <MessageParts>
    <LedgerJournalTable class="entity">
    <z>50</z>
    <LedgerJournalTrans class="entity'>
    <xsl:apply-templates select="Invoice"/>
    </LedgerJournalTrans>
    <LedgerJournalTrans class="entity'>
    <xsl:for-each select="Product">
    <xsl:apply-templates select="Product"/>
    </xsl:for-each>
    </LedgerJournalTrans>
    </LedgerJournalTable>
    </MessageParts>
  </xsl:template>

  <xsl:template match="Invoice">
  <e><xsl:value-of select="normalize-space(a/text()[1])"/></e>
  </xsl:template>


   <xsl:template match="Product">
  <g><xsl:value-of select="normalize-space(b/text()[1])"/></g>
  <h><xsl:value-of select="normalize-space(c/text()[1])"/></h>
  </xsl:template>

</xsl:stylesheet>

And i had posted a wrong question earlier, so sorry for that

Upvotes: 0

Views: 54

Answers (1)

Progman
Progman

Reputation: 19555

Ident your XML document to see which element is nested in what other element. When you indent your XML document it will look like this:

<InvoiceDocument>
    <Invoice>
        <d>100</d>
        <a>120</a>
        <Products>
            <Product>
                <b>11</b>
                <c>12</c>
            </Product>
            <Product>
                <b>13</b>
                <c>14</c>
            </Product>
        </Products>
    </Invoice>
</InvoiceDocument>

As you see now, the root element <InvoiceDocument> does not have any <Product> or <Products> elements. This means that <xsl:for-each select="Product"> will not find anything.

Inside your matching for the <Invoice> element, add XSLT selectors/operators to access the <Products> element.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="InvoiceDocument">
    <MessageParts>
        <LedgerJournalTable class="entity">
            <z>50</z>
            <xsl:apply-templates select="Invoice"/>
        </LedgerJournalTable>
    </MessageParts>
  </xsl:template>

  <xsl:template match="Invoice">
      <LedgerJournalTrans class="entity">
          <e><xsl:value-of select="normalize-space(a/text()[1])"/></e>
      </LedgerJournalTrans>
      <xsl:apply-templates select="Products" /> <!-- handle products here -->
  </xsl:template>

  <xsl:template match="Product">
      <LedgerJournalTrans class="entity">
          <g><xsl:value-of select="normalize-space(b/text()[1])"/></g>
          <h><xsl:value-of select="normalize-space(c/text()[1])"/></h>
      </LedgerJournalTrans>
  </xsl:template>

</xsl:stylesheet>

This will generate the following XML document:

<MessageParts>
    <LedgerJournalTable class="entity">
        <z>50</z>
        <LedgerJournalTrans class="entity">
            <e>120</e>
        </LedgerJournalTrans>
        <LedgerJournalTrans class="entity">
            <g>11</g>
            <h>12</h>
        </LedgerJournalTrans>
        <LedgerJournalTrans class="entity">
            <g>13</g>
            <h>14</h>
        </LedgerJournalTrans>
    </LedgerJournalTable>
</MessageParts>

Upvotes: 1

Related Questions