Muenchian 分组 XSLT 1.0 多重分组

Posted

技术标签:

【中文标题】Muenchian 分组 XSLT 1.0 多重分组【英文标题】:Muenchian grouping XSLT 1.0 multiple grouping 【发布时间】:2021-11-20 13:06:47 【问题描述】:

我读过类似的帖子,但不知道如何在 XSLT 1.0 中基于多列应用 Muenchian 分组。

我被最糟糕的 XML 文件所困扰,无法更改布局。这是一个示例:

<DataSet>
    <Row>
        <Cells>
            <Cell>COMPANY-A</Cell>
            <Cell>VG-ALG-TAX</Cell>
            <Cell>2021000009</Cell>
            <Cell>F29888</Cell>
        </Cells>
    </Row>
    <Row>
        <Cells>
            <Cell>COMPANY-A</Cell>
            <Cell>VG-ALG-TAX</Cell>
            <Cell>2021000010</Cell>
            <Cell>F12350</Cell>
        </Cells>
    </Row>
    <Row>
        <Cells>
            <Cell>COMPANY-A</Cell>
            <Cell>VG-ALG-TAX</Cell>
            <Cell>2021000010</Cell>
            <Cell>F12135</Cell>
        </Cells>
    </Row>
    <Row>
        <Cells>
            <Cell>COMPANY-B</Cell>
            <Cell>VG-ALG-TAX</Cell>
            <Cell>2021000010</Cell>
            <Cell>F12350</Cell>
        </Cells>
    </Row>
</DataSet>

我想在 XSLT1.0 中使用 Muenchian 分组来按第一个、第二个和第三个单元格进行分组。第四个单元格需要链接到该键。预期结果:

<DataSet>
    <Invoice>
        <Key>
            <Company>COMPANY-A</Company>
            <Type>VG-ALG-TAX</Type>
            <Num>2021000009</Num>
        </Key>
        <Customers>
            <Customer>F29888</Customer>
        </Customers>
    </Invoice>
    <Invoice>
        <Key>
            <Company>COMPANY-A</Company>
            <Type>VG-ALG-TAX</Type>
            <Num>2021000010</Num>
        </Key>
        <Customers>
            <Customer>F12350</Customer>
            <Customer>F12135</Customer>
        </Customers>
    </Invoice>
    <Invoice>
        <Key>
            <Company>COMPANY-B</Company>
            <Type>VG-ALG-TAX</Type>
            <Num>2021000010</Num>
        </Key>
        <Customers>
            <Customer>F12350</Customer>
        </Customers>
    </Invoice>
</DataSet>

我试过这个,但没有结果:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

<xsl:output method="xml" indent="yes"/>

<xsl:key name="document-by-number" match="GenericBrowseResponse/Select/Response/Selection/DataSet/Row" use="Cells/Cell[2]"></xsl:key>

<xsl:template match="GenericBrowseResponse/Select/Response/Selection/DataSet/Row">
    <Invoices>
        <xsl:apply-templates select="Cells[generate-id(.)=generate-id(key('document-by-number',Cells/Cell[2])[1])]"/>
    </Invoices>
</xsl:template>

<xsl:template match="Cells">
    <Invoice>
        <xsl:for-each select="key('document-by-number', Cell[2])">
            <Document><xsl:value-of select="Cell[3]"/></Document>
        </xsl:for-each> 
    </Invoice>
</xsl:template>

<xsl:template match="text()"></xsl:template>

</xsl:stylesheet>

【问题讨论】:

“我试过这个,但没有结果:” 这不是真的。有一个结果 - 只是不是您期望的结果:xsltfiddle.liberty-development.net/jxWZS8e 那是因为您的样式表与这里需要的相去甚远。看起来您只是复制/粘贴了一些随机代码,并希望它能以某种方式工作。 从我在类似问题中发现的内容中,我确实没有很多 sn-ps。我不知道如何走上正轨。你能@michael.hor257k 给我一些建议吗? 我的建议是放弃巫毒编程并学习 Muenchian 分组:jenitennison.com/xslt/grouping/muenchian.html 这里给你一个提示:将你的密钥定义为&lt;xsl:key name="k1" match="Cells" use="concat(Cell[1], '|', Cell[2], '|', Cell[3])" /&gt;。这是这里唯一的复杂之处 - 其余的是标准的 Muenchian 方法。 @michael.hor257k 谢谢,提示为我指明了正确的方向。仍然有点怀疑这是否是正确的解决方案,但它成功了。 【参考方案1】:

尝试了定义键的方式的一些可能性,用下面的代码解决了这个问题:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="xml" indent="yes"/>

<xsl:key name="k1" match="Cells" use="concat(Cell[1], '|', Cell[2], '|', Cell[3])" />
<!--<xsl:key name="k1" match="Cells" use="Cell[3]"></xsl:key>-->

<xsl:template match="/DataSet">
  <DataSet>
  <xsl:apply-templates select="Row/Cells[generate-id()=generate-id(key('k1',concat(Cell[1], '|', Cell[2], '|', Cell[3]))[1])]"/>
  </DataSet>
</xsl:template>

<xsl:template match="Row/Cells">
    <Invoice>
      <Key>
        <Company><xsl:value-of select="Cell[1]"/></Company>
        <Type><xsl:value-of select="Cell[2]"/></Type>
        <Num><xsl:value-of select="Cell[3]"/></Num>
      </Key>
      <Customer>
        <xsl:for-each select="key('k1', concat(Cell[1], '|', Cell[2], '|', Cell[3]))">
            <Customers><xsl:value-of select="Cell[4]"/></Customers>
        </xsl:for-each> 
      </Customer>
    </Invoice>
</xsl:template>

<xsl:template match="text()"></xsl:template>

</xsl:stylesheet>

【讨论】:

以上是关于Muenchian 分组 XSLT 1.0 多重分组的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Muenchian 分组 XSLT 1.0 在每个目录中按标题分组

使用 XSLT 对 HTML 输出进行分组(muenchian 分组?)

XSLT 1.0- 使用 Muenchian 方法创建表

使用 XSLT muenchian-grouping 进行嵌套分组

将 Muenchian 分组应用于 XSLT

XSLT 和 Muenchian 分组, 多级样本