繁体   English   中英

使用Muenchian方法进行XSLT多级分组

[英]XSLT multilevel grouping using Muenchian method

在此先感谢您的时间。 我有一个深层嵌套的XML,我需要执行其XSLT 1.0转换(用于pdf生成)。 我正在部分粘贴XML,对此我已经表示歉意!

我根据几个答案重新调整了XML,如下所示,我意识到自己遇到了更多问题。 感谢您的耐心等待。

请让我知道是否需要任何其他说明。

输入XML

 <Reports>
  <Report>
    <ReportID>R123</ReportID>
    <ReportName>R123Name</ReportName>
    <PurchaseTypes>
      <PurchaseType>
        <Name>Purchase Type 2</Name>
        <Areas>
          <Area>
            <AreaType>American</AreaType>
            <AreaName>IL</AreaName>
            <SaleDetails>
              <SaleDetail>
                <SaleDetailID>
                  SD45
                </SaleDetailID>
                <Amount>
                  177.3
                </Amount>
              </SaleDetail>
              <SaleDetail>
                <SaleDetailID>
                  SD56
                </SaleDetailID>
                <Amount>
                  123
                </Amount>
              </SaleDetail>
            </SaleDetails>
          </Area>
          <Area>
            <AreaType>American</AreaType>
            <AreaName>MN</AreaName>
            <SaleDetails>
              <SaleDetail>
                <SaleDetailID>
                  SD19
                </SaleDetailID>
                <Amount>
                  19
                </Amount>
              </SaleDetail>

            </SaleDetails>
          </Area>
        </Areas>
      </PurchaseType>
    </PurchaseTypes>
  </Report>
</Reports>

需要的输出类似于下图

示例图片2: https//picasaweb.google.com/lh/photo/hxTUY6Qv_9eJyvxQ-UhQutMTjNZETYmyPJy0liipFm0?feat = directlink

@DevNull,这是我正在尝试的:

  <xsl:template match="Report">
        <xsl:apply-templates select="ReportID|PurchaseTypes/PurchaseType"></xsl:apply-templates>
      </xsl:template>

 <xsl:template match="PurchaseType">
    <xsl:apply-templates select="Name|Areas/Area/AreaType"></xsl:apply-templates>
  </xsl:template>

但是我两次见到美洲类型的区域。 像这样:R123购买Type 2 American American

查看您的输入XML和所需输出的excel图像,它看起来仍然不需要分组。 XML似乎已经按照您需要格式化报告的方式进行了组织。

这是一个使用XSL-FO创建PDF的示例。

您的XML输入:

<Reports>
  <Report>
    <ReportID>R123</ReportID>
    <ReportName>R123Name</ReportName>
    <PurchaseTypes>
      <PurchaseType>
        <Name>Purchase Type 2</Name>
        <SaleDetails>
          <SaleDetail>
            <SaleDetailID>
              SD45
            </SaleDetailID>
            <Amount>
              177.3
            </Amount>
          </SaleDetail>
          <SaleDetail>
            <SaleDetailID>
              SD56
            </SaleDetailID>
            <Amount>
              123
            </Amount>
          </SaleDetail>
        </SaleDetails>
      </PurchaseType>
    </PurchaseTypes>
  </Report>
  <Report>
    <ReportID>R234</ReportID>
    <ReportName>R234Name</ReportName>
    <PurchaseTypes>
      <PurchaseType>
        <Name>Purchase Type 1</Name>
        <SaleDetails>
          <SaleDetail>
            <SaleDetailID>
              SD456
            </SaleDetailID>
            <Amount>
              17.3
            </Amount>
          </SaleDetail>
          <SaleDetail>
            <SaleDetailID>
              SD556
            </SaleDetailID>
            <Amount>
              23
            </Amount>
          </SaleDetail>
        </SaleDetails>
      </PurchaseType>
      <PurchaseType>
        <Name>Purchase Type 2</Name>
        <SaleDetails>
          <SaleDetail>
            <SaleDetailID>
              SD451
            </SaleDetailID>
            <Amount>
              12.2
            </Amount>
          </SaleDetail>
        </SaleDetails>
      </PurchaseType>
    </PurchaseTypes>
  </Report>
</Reports>

转换为以下样式表:

<xsl:stylesheet version="1.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:attribute-set name="reportBorder" use-attribute-sets="reportPadding">
    <xsl:attribute name="border">solid 1pt black</xsl:attribute>
  </xsl:attribute-set>

  <xsl:attribute-set name="reportPadding">
    <xsl:attribute name="padding-left">4pt</xsl:attribute>
    <xsl:attribute name="padding-right">4pt</xsl:attribute>
    <xsl:attribute name="padding-top">2pt</xsl:attribute>
    <xsl:attribute name="padding-bottom">2pt</xsl:attribute>    
  </xsl:attribute-set>

  <xsl:template match="Reports">
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <fo:layout-master-set>
        <fo:simple-page-master master-name="my-page" page-width="8.5in" page-height="11in">
          <fo:region-body margin="1in" margin-top="1.5in" margin-bottom="1.5in"/>
        </fo:simple-page-master>
      </fo:layout-master-set>
      <fo:page-sequence master-reference="my-page">
        <fo:flow flow-name="xsl-region-body">
          <xsl:apply-templates/>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template>

  <xsl:template match="Report">
    <fo:table margin-bottom="12pt" border="solid 2pt black" width="2.5in">
      <fo:table-column column-number="1" width="1.5in"/>
      <fo:table-column column-number="2" width="1in"/>
      <fo:table-body>
        <xsl:apply-templates select="ReportID|PurchaseTypes/PurchaseType/Name"/>
      </fo:table-body>
    </fo:table>
  </xsl:template>

  <xsl:template match="ReportID">
    <fo:table-row>
      <fo:table-cell background-color="#FFFF00" border-top="solid 2pt black" border-left="solid 2pt black" xsl:use-attribute-sets="reportPadding">
        <fo:block><xsl:value-of select="."/></fo:block>
      </fo:table-cell>
      <fo:table-cell border-top="solid 2pt black" border-right="solid 2pt black">
        <fo:block>&#xA0;</fo:block>
      </fo:table-cell>
    </fo:table-row>    
  </xsl:template>

  <xsl:template match="Name">
    <xsl:if test="ancestor-or-self::PurchaseType[preceding-sibling::PurchaseType]">
      <fo:table-row border-left="solid 2pt black">
        <fo:table-cell>
          <fo:block>&#xA0;</fo:block>
        </fo:table-cell>
        <fo:table-cell>
          <fo:block>&#xA0;</fo:block>
        </fo:table-cell>
      </fo:table-row>
    </xsl:if>
    <fo:table-row>
      <fo:table-cell background-color="#DDA0DD" border-left="solid 2pt black" xsl:use-attribute-sets="reportPadding">
        <fo:block><xsl:value-of select="normalize-space(.)"/></fo:block>
      </fo:table-cell>
      <fo:table-cell border-right="solid 2pt black">
        <fo:block>&#xA0;</fo:block>
      </fo:table-cell>
    </fo:table-row>    
    <fo:table-row background-color="#8FBC8F">
      <fo:table-cell xsl:use-attribute-sets="reportBorder">
        <fo:block>Sale Detail ID</fo:block>
      </fo:table-cell>
      <fo:table-cell xsl:use-attribute-sets="reportBorder">
        <fo:block>Amount</fo:block>
      </fo:table-cell>
    </fo:table-row>
    <xsl:apply-templates select="following-sibling::SaleDetails/SaleDetail"/>
  </xsl:template>

  <xsl:template match="SaleDetail">
    <fo:table-row>
      <fo:table-cell xsl:use-attribute-sets="reportBorder">
        <fo:block><xsl:value-of select="normalize-space(SaleDetailID)"/></fo:block>
      </fo:table-cell>
      <fo:table-cell xsl:use-attribute-sets="reportBorder" text-align="right">
        <fo:block><xsl:value-of select="normalize-space(Amount)"/></fo:block>
      </fo:table-cell>
    </fo:table-row>    
  </xsl:template>
</xsl:stylesheet>

产生此PDF:

在此处输入图片说明

希望发生的事情不会在FO标记中丢失。

这不是分组问题。 我本人对Meunchian还是很陌生,所以我什至无法真正描述如何使用它,因此我将参考W3C

键提供了一种处理包含隐式交叉引用结构的文档的方法。

Jeni Tennison

分组是XSLT样式表中的一个常见问题:如何获取元素列表并将其分组。 在两种主要情况下,您需要执行此操作:

  • 按内容分组(例如将来自诺丁汉的所有人员分组)
  • 按位置分组(例如,每个列表分组10个项目)

因为您的所有数据都是非常分层的,所以很容易一遍又一遍地在树上工作,从后代组移动到后代组。

这是完整的解决方案:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:variable name="newline" select="'&#13;&#10;'"/>
  <xsl:variable name="tab" select="'&#9;'"/>

  <xsl:template match="/Reports">
    <xsl:apply-templates select="descendant::Report"/>
  </xsl:template>

  <xsl:template match="Report">
    <xsl:value-of select="ReportID"/>
    <xsl:value-of select="$newline"/>
    <xsl:apply-templates select="descendant::PurchaseType"/>
  </xsl:template>

  <xsl:template match="PurchaseType">
    <xsl:value-of select="Name"/>
    <xsl:value-of select="$newline"/>
    <xsl:text>Sale Detail ID</xsl:text>
    <xsl:value-of select="concat($tab,$tab)"/>
    <xsl:text>Amount</xsl:text>
    <xsl:value-of select="$newline"/>
    <xsl:apply-templates select="descendant::SaleDetail"/>
    <xsl:value-of select="$newline"/>
  </xsl:template>

  <xsl:template match="SaleDetail">
    <xsl:value-of select="normalize-space(SaleDetailID)"/>
    <xsl:value-of select="concat($tab,$tab,$tab)"/>
    <xsl:value-of select="normalize-space(Amount)"/>
    <xsl:value-of select="$newline"/>
  </xsl:template>
</xsl:stylesheet>

产生以下内容(我必须将选项卡转换为用于SO格式化的空格)。 理由与您的形象不符:

R123
Purchase Type 2
Sale Detail ID              Amount
SD45                        177.3
SD56                        123

R234
Purchase Type 1
Sale Detail ID              Amount
SD456                       17.3
SD556                       23

Purchase Type 2
Sale Detail ID              Amount
SD451                       12.2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM