Многоуровневая группировка XSLT с использованием метода Мюнхена - PullRequest
2 голосов
/ 31 января 2012

Заранее спасибо за ваше время.У меня есть глубоко вложенный 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 Тип покупки 2 Американец Американский

Ответы [ 2 ]

1 голос
/ 02 февраля 2012

Глядя на ваш входной XML и превосходное изображение желаемого результата, он все равно не выглядит так, как будто вам нужна группировка.Кажется, что 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:

enter image description here

Надеемся, что происходящее не потеряно в FOразметки.

0 голосов
/ 01 февраля 2012

Это не проблема группировки.Я сам новичок в Meunchian, поэтому не могу даже описать, как его использовать, поэтому я отложу до W3C :

.для работы с документами, которые содержат неявную структуру перекрестных ссылок.

и Джени Теннисон :

Группировка является распространенной проблемой в таблицах стилей XSLT:как взять список элементов и распределить их по группам.Есть две основные ситуации, в которых вам нужно это сделать:

  • группировка по контенту (например, группировка всех людей из Ноттингема)
  • группировка по позиции (например, группировка 10 элементов вlist)

Поскольку все ваши данные очень иерархичны, очень просто пройтись по дереву за один проход, перейдя от группы-потомка к группе-потомку.

Вот полное решение:

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