2012-01-31 1 views
2

Заранее благодарим за ваше время. У меня есть глубоко вложенный XML, преобразование XSLT 1.0, которое мне нужно выполнить (для создания pdf). Я частично вставляю XML и уже прошу прощения за это!Многоуровневая группировка XSLT с использованием метода Muenchian

Я изменил 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> 

Выход необходимо похоже на изображение ниже

Sample Image 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 Американский American

+0

Ваш запрошенный выход не имеет необходимого углубления, поэтому от него невозможно угадать любую группировку. Пожалуйста, отредактируйте и исправьте. –

+0

Thanks Dimitre; Я уточняю свой вопрос для получения дополнительной информации. Это форматирование, которое мне нужно, но я попытаюсь немного отложить его. – m27

ответ

1

Глядя на ваш входной 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

Спасибо Захари и Девнулл. Это именно то, что я ищу, но приношу свои извинения, так как я хотел бы просить об этом еще несколько объяснений, поскольку я все еще не понимаю на этом 100%. Как вы можете вспомнить, более ранний образец XML, который я опубликовал, имел несколько уровней вложенности. Я редактирую свой предыдущий XML еще раз. Я благодарю вас за ваше терпение, поскольку с вашими объяснениями мои концепции становятся яснее, и я могу уточнить свой вопрос. Для обновленного XML я в основном представил еще один уровень гнездования для решения моей проблемы. – m27

+0

Не могу сделать +2 для FO/PDF, так что просто +1, извините. –

+0

Благодарим вас за ваши ответы и разъяснения. – m27

0

Это не проблема группирования. Я очень новый для 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 
+0

Спасибо Захари за ваши указатели. Я думаю, что я не прояснил себя правильно. Дело в том, что возможно, что данный отчет имеет продажи только для бренда типа 1. Similary, продажа может быть только для американского типа и т. Д. Следовательно, я думал о группировке. Если я попытаюсь использовать // BrandType, по сути, я получу декларацию для всех типов брендов в документе XML, а не только тип бренда под этим типом области для данного отчета. Я уточняю свой вопрос для получения дополнительной информации. – m27

+0

@questiontoask: Хорошо. Помните, что выбор «// BrandType» был только началом. Как бы то ни было, ваш вопрос ставит большую нагрузку на кого-то, кто пытается ответить, чтобы выяснить, что именно «... возможно, что данный отчет имеет продажи только для бренда типа 1. Similary, продажа ...» означает , Можете ли вы предоставить меньший, более конкретный источник XML и правильно отформатированный вывод, который подчеркивает эти требования? –

+0

Я укоротил XML. Кроме того, поскольку я не мог загрузить изображение (как новый пользователь), я разместил ссылку на picasa, где я загрузил желаемое выходное изображение. В очередной раз благодарим за помощь. – m27