1

我意识到您不能在 xsl 中使用数组,通常要执行下面的任务需要一个数组。这就是我需要的...

示例 xml 代码...

<products>
 <product>
  <productNumber>1</productNumber>
  <productType>TypeA</productType>
 </product>
 <product>
  <productNumber>2</productNumber>
  <productType>TypeB</productType>
 </product>
 <product>
  <productNumber>3</productNumber>
  <productType>TypeA</productType>
 </product>
 <product>
  <productNumber>4</productNumber>
  <productType>TypeC</productType>
 </product>
 <product>
  <productNumber>5</productNumber>
  <productType>TypeA</productType>
 </product>
</products>

上面是一个独特的“产品”列表,每个产品都分配有一个“产品类型”,可以在整个 xml 中重复多次。我希望 xsl 为每个“productType”提取一个条目而不重复。

上面的最终结果将是......

TypeA
TypeB
TypeC

并不是 ....

TypeA
TypeB
TypeA
TypeC
TypeA

我不可能是唯一一个寻找这种功能的人。

想法?

4

2 回答 2

1

这种转变

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kProdByType"
      match="product" use="productType"/>

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

 <xsl:template match="/products">
  <products>
    <xsl:apply-templates select=
     "product[generate-id()
             =
             generate-id(key('kProdByType', productType)[1])
             ]
     "/>
  </products>
 </xsl:template>

 <xsl:template match="product">
   <productType value="{productType}">
    <xsl:apply-templates mode="copy"
     select="key('kProdByType', productType)"/>
   </productType>
 </xsl:template>

 <xsl:template match="product" mode="copy">
  <xsl:call-template name="identity"/>
 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时:

<products>
 <product>
  <productNumber>1</productNumber>
  <productType>TypeA</productType>
 </product>
 <product>
  <productNumber>2</productNumber>
  <productType>TypeB</productType>
 </product>
 <product>
  <productNumber>3</productNumber>
  <productType>TypeA</productType>
 </product>
 <product>
  <productNumber>4</productNumber>
  <productType>TypeC</productType>
 </product>
 <product>
  <productNumber>5</productNumber>
  <productType>TypeA</productType>
 </product>
</products>

产生所需的正确分组

<products>
    <productType value="TypeA">
        <product>
            <productNumber>1</productNumber>
            <productType>TypeA</productType>
        </product>
        <product>
            <productNumber>3</productNumber>
            <productType>TypeA</productType>
        </product>
        <product>
            <productNumber>5</productNumber>
            <productType>TypeA</productType>
        </product>
    </productType>
    <productType value="TypeB">
        <product>
            <productNumber>2</productNumber>
            <productType>TypeB</productType>
        </product>
    </productType>
    <productType value="TypeC">
        <product>
            <productNumber>4</productNumber>
            <productType>TypeC</productType>
        </product>
    </productType>
</products>

请注意:这是著名的Muenchian 分组方法示例,它是 XSLT 1.0 中已知最快的分组技术。

XSLT 2.0 解决方案

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

 <xsl:template match="/products">
   <xsl:for-each-group select="product"
        group-by="productType">
     <productType value="{productType}">
      <xsl:apply-templates select="current-group()"/>
     </productType>
   </xsl:for-each-group>
 </xsl:template>
</xsl:stylesheet>

当这个 XSLT 2.0 转换应用于提供的 XML 文档时,会产生完全相同的、正确分组的结果

于 2010-08-16T17:26:05.783 回答
0

Dimitre 让我走上了正确的道路。这是我想出的满足我需要的代码,一个简单的分隔输出流以支持 AJAX 调用......

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8"/>
<xsl:key name="kProdByBrand" match="Products/Product" use="Brand"/>

 <xsl:template match="Products">
   <xsl:for-each 
     select="Product
     [generate-id() = generate-id(key('kProdByBrand', Brand)[1])]"><xsl:sort
     select="Brand" /><xsl:value-of select="Brand" />|</xsl:for-each>
 </xsl:template>

</xsl:stylesheet>

给定一个 xml,它有许多看起来像这样的成员......

<Product>
    <Brand>Brand</Brand>
    <OldPN>myCompany Part Number</OldPN>    
            ...
</Product>

输出看起来像这样......

Brand|Brand1|Brand2|Brand3|
于 2010-08-17T18:16:07.203 回答