需要帮助:XSLT 1.0对项目的描述进行分组

时间:2018-04-01 09:41:07

标签: xml xpath xslt-1.0

我有一个问题是根据来自不同路径(/catalog/Invoice/InvoiceItem)的说明,在一个路径(/catalog/TypeDesc)中对某些项目进行分组。

输入XML:

<catalog>
  <Invoice>
    <InvoiceItem Id="G001">
        <Charge Amount="10.000"/>
    </InvoiceItem>
    <InvoiceItem Id="G002">
        <Charge Amount="5.000"/>
    </InvoiceItem>
    <InvoiceItem Id="G003">
        <Charge Amount="50.000"/>
    </InvoiceItem>
    <InvoiceItem Id="G004">
        <Charge Amount="0.500"/>
    </InvoiceItem>
  </Invoice>

  <TypeDesc PKey="G001" LongDes="Local"/>
  <TypeDesc PKey="G002" LongDes="Local"/>
  <TypeDesc PKey="G003" LongDes="Roaming"/>
  <TypeDesc PKey="G004" LongDes="Local"/>
</catalog>

我的代码基于此处的示例6.3:http://www.kosek.cz/xml/xslt/seskupovani.html

<xsl:for-each select="//InvoiceItem">
 <xsl:sort select="//TypeDesc[@PKey = current()/@Id]/@LongDes"/>
 <xsl:variable name="item" select="//TypeDesc[@PKey = current()/@Id]/@LongDes"/>
 <xsl:if test="not(//TypeDesc[@PKey = preceding-sibling::InvoiceItem/@Id]/@LongDes = $item)">
      <fo:block font-weight="bold">Group: <xsl:value-of select="$item"/></fo:block>
 </xsl:if>
 <fo:block><xsl:value-of select="$item"/></fo:block>
</xsl:for-each>

我的问题是排序正确执行,但分组失败。

预期输出应为:

Group: Local
Local
Local
Local
Group: Roaming
Roaming

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

您仍然可以使用Muenchian分组,您只需要交叉引用该描述,这里是一个输出HTML的示例,但您可以将其调整为输出FO:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exsl="http://exslt.org/common"
    xmlns:msxml="urn:schemas-microsoft-com:xslt"
    exclude-result-prefixes="exsl msxml"
    version="1.0">

  <xsl:output method="html" indent="yes" version="5" doctype-system="about:legacy-doctype"/>

  <xsl:key name="desc-ref" match="TypeDesc" use="@PKey"/>
  <xsl:key name="item-group" match="InvoiceItem" use="/catalog/TypeDesc[@PKey = current()/@Id]/@LongDes"/>

  <xsl:template match="catalog">
      <xsl:for-each select="Invoice/InvoiceItem[generate-id() = generate-id(key('item-group', key('desc-ref', @Id)/@LongDes)[1])]">
          <div>
              <h2>
                  <xsl:value-of select="key('desc-ref', @Id)/@LongDes"/>
              </h2>
              <ul>
                  <xsl:for-each select="key('item-group', key('desc-ref', @Id)/@LongDes)">
                      <li>
                          <xsl:value-of select="concat(@Id, ': ', key('desc-ref', @Id)/@LongDes, '; Amount: ', Charge/@Amount) "/>
                      </li>
                  </xsl:for-each>                  
              </ul>
          </div>
      </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

http://xsltfiddle.liberty-development.net/94hvTyN