Question

XML INPUT

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <InvNum>
        <InvNum>10001</InvNum>
        <BatchNumber>
            <BatchNumber>201400013002</BatchNumber>
            <SeqNumber>
                <SeqNumber>2</SeqNumber>
                <InvoiceItem>
                    <a>122223</a>
                    <b>111</b>
                </InvoiceItem>
            </SeqNumber>
        </BatchNumber>
    </InvNum>
    <InvNum>
        <InvNum>10002</InvNum>
        <BatchNumber>
            <BatchNumber>201400013002</BatchNumber>
            <SeqNumber>
                <SeqNumber>2</SeqNumber>
                <InvoiceItem>
                    <a>123</a>
                    <b>456</b>
                </InvoiceItem>
                <InvoiceItem>
                    <a>33</a>
                    <b>99</b>
                </InvoiceItem>
            </SeqNumber>
        </BatchNumber>
    </InvNum>
</data>

Desired output

<?xml version="1.0" encoding="UTF8"?>
<data>
    <Invoice>
        <BatchNumber>201400013002</BatchNumber>
        <SeqNumber>2</SeqNumber>
        <InvNum>10001</InvNum>
        <InvoiceItem>
            <a>122223</a>
            <b>111</b>
        </InvoiceItem>
    </Invoice>
    <Invoice>
        <BatchNumber>201400013002</BatchNumber>
        <SeqNumber>2</SeqNumber>
        <InvNum>10002</InvNum>
        <InvoiceItem>
            <a>123</a>
            <b>456</b>
        </InvoiceItem>
        <InvoiceItem>
            <a>33</a>
            <b>99</b>
        </InvoiceItem>
    </Invoice>
</data>

This is my XSL

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rpt="Invoice">
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <!--suppress group and detail_collection-->
    <xsl:template match="rpt:Detail_Collection|rpt:BatchNumber_Collection|rpt:SeqNumber_Collection|rpt:InvNum_Collection">
        <xsl:apply-templates/>
    </xsl:template>
    <!--end suppress all group collection-->
    <!-- create node for Invoice and copy child nodes to it-->
    <xsl:template match="rpt:InvNum">
        <xsl:element name="InvoiceNumber">
            <xsl:element name="BatchNumber">
                <xsl:value-of select="//rpt:BatchNumber/text()"/>
            </xsl:element>
            <xsl:element name="SeqNumber">
                <xsl:value-of select="//rpt:SeqNumber/text()"/>
            </xsl:element>
            <xsl:element name="InvNum">
                <xsl:value-of select="rpt:InvNum/text()"/>
            </xsl:element>
            <xsl:call-template name="SUBCHILDS"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="rpt:InvoiceItem" name="SUBCHILDS">
        <xsl:element name="InvoiceItem">
            <xsl:element name="a">
                <xsl:value-of select="//a"/>
            </xsl:element>
            <xsl:element name="b">
                <xsl:value-of select="//b"/>
            </xsl:element>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

I am using SSRS and exporting data to XML using XSLT to get the desired output. I need to remove the group headers like BatchNumber and Seqnumber but show its value and move Invnum element down the order. With my xsl, I am getting only first record. It is not not able to loop through the nodes to the next records. Any help in pointing the issue or fixing this is appreciated. Thanks in advance.

Était-ce utile?

La solution

I have created additional nodes before InvoiceItem in the following input XML:

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <InvNum>
        <InvNum>10001</InvNum>
        <BatchNumber>
            <BatchNumber>201400013002</BatchNumber>
            <SeqNumber>
                <add>ADDITIONAL NODE1</add>
                <add>ADDITIONAL NODE2</add>
                <SeqNumber>2</SeqNumber>
                <InvoiceItem>
                    <a>122223</a>
                    <b>111</b>
                </InvoiceItem>
            </SeqNumber>
        </BatchNumber>
    </InvNum>
    <InvNum>
        <InvNum>10002</InvNum>
        <BatchNumber>
            <BatchNumber>201400013002</BatchNumber>
            <SeqNumber>
                <add>ADDITIONAL NODE3</add>
                <add>ADDITIONAL NODE4</add>
                <SeqNumber>2</SeqNumber>
                <InvoiceItem>
                    <a>123</a>
                    <b>456</b>
                </InvoiceItem>
                <InvoiceItem>
                    <a>33</a>
                    <b>99</b>
                </InvoiceItem>
            </SeqNumber>
        </BatchNumber>
    </InvNum>
</data>

using the following stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:rpt="Invoice" 
    exclude-result-prefixes="rpt">

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="data/InvNum">
        <Invoice>
            <xsl:apply-templates select="BatchNumber/BatchNumber"/>
            <xsl:apply-templates select="BatchNumber/SeqNumber/SeqNumber"/>
            <xsl:apply-templates select="InvNum"/>
            <xsl:apply-templates select="BatchNumber/SeqNumber"/>
        </Invoice>
    </xsl:template>

    <xsl:template match="InvNum/BatchNumber">
        <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="BatchNumber/SeqNumber">
        <xsl:apply-templates select="*[not(self::SeqNumber)]"/>
    </xsl:template>

</xsl:stylesheet>

it outputs:

<?xml version="1.0" encoding="utf-8"?>
<data>
   <Invoice>
      <BatchNumber>201400013002</BatchNumber>
      <SeqNumber>2</SeqNumber>
      <InvNum>10001</InvNum>
      <add>ADDITIONAL NODE1</add>
      <add>ADDITIONAL NODE2</add>
      <InvoiceItem>
         <a>122223</a>
         <b>111</b>
      </InvoiceItem>
   </Invoice>
   <Invoice>
      <BatchNumber>201400013002</BatchNumber>
      <SeqNumber>2</SeqNumber>
      <InvNum>10002</InvNum>
      <add>ADDITIONAL NODE3</add>
      <add>ADDITIONAL NODE4</add>
      <InvoiceItem>
         <a>123</a>
         <b>456</b>
      </InvoiceItem>
      <InvoiceItem>
         <a>33</a>
         <b>99</b>
      </InvoiceItem>
   </Invoice>
</data>

Autres conseils

Maybe not the most elegant way, but the next XSLT does the trick:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rpt="Invoice" xmlns="Invoice" exclude-result-prefixes="rpt">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

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

    <xsl:template match="rpt:InvNum[child::rpt:InvNum]">
        <Invoice>
            <xsl:apply-templates select="rpt:BatchNumber/rpt:BatchNumber" />
            <xsl:apply-templates select="rpt:BatchNumber/rpt:SeqNumber/rpt:SeqNumber" />
            <xsl:apply-templates select="rpt:InvNum" />
            <xsl:apply-templates select="rpt:BatchNumber/rpt:SeqNumber/rpt:InvoiceItem" />
        </Invoice>
    </xsl:template>
</xsl:stylesheet>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top