在循环遍历节点时删除组头并移动元素

时间:2014-03-20 20:05:16

标签: xml xslt reporting-services xslt-1.0

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>

所需的输出

<?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>

这是我的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>

我正在使用SSRS并使用XSLT将数据导出到XML以获得所需的输出。 我需要删除像BatchNumber和Seqnumber这样的组头,但要显示其值并按顺序移动Invnum元素。有了我的xsl,我只获得了第一张唱片。它无法通过节点循环到下一个记录。 任何帮助指出问题或解决这个问题表示赞赏。提前致谢。

2 个答案:

答案 0 :(得分:0)

也许不是最优雅的方式,但下一个XSLT可以解决这个问题:

<?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>

答案 1 :(得分:0)

我在以下输入XML中InvoiceItem之前创建了其他节点

<?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>

使用以下样式表:

<?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>

输出:

<?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>