0

我对 XSLT 有点陌生,所以我为这个基本问题道歉。

我正在尝试创建一个 XSL 样式表,该样式表将从 XML(下方)中提取第三个<cell> - 即 CODE1、CODE2 - 每个节点的值并将其放入下拉框中。我还想比较每个节点并取出任何重复的内容,以便它只显示 CODE1 和 CODE2 的一个实例,而不是 CODE1、CODE1、CODE2。

XML:

<dvm>
  <description>This is a description</description>
  <columns>
    <column name="lang"/>
    <column name="text"/>
    <column name="code" qualifier="true" order="1"/>
    <column name="comm" qualifier="true" order="2"/>
    <column name="subj"/>
    <column name="copy"/>
    <column name="flag"/>
 </columns>
 <rows>
   <row>
     <cell>English</cell>
     <cell></cell>
     <cell>CODE1</cell>
     <cell>Fixed</cell>
     <cell>Title1</cell>
     <cell/><cell/>
     <cell/><cell/>
  </row>
  <row>
     <cell>English</cell>
     <cell></cell>
     <cell>CODE1</cell>
     <cell>Wired</cell>
     <cell>Title2</cell>
     <cell/><cell/>
     <cell/><cell/>
  </row>
  <row>
     <cell>English</cell>
     <cell></cell>
     <cell>CODE2</cell>
     <cell>Fixed</cell>
     <cell>Title3</cell>
     <cell/><cell/>
     <cell/><cell/>
  </row>
</dvm>
4

2 回答 2

2

删除重复项是通常称为“分组”的一类问题的特例。XSLT 2.0 中有几个特性可以帮助解决分组问题,distinct-values() 函数和 xsl:for-each-group 指令。在 XSLT 1.0 中更难:搜索“Muenchian grouping”(或者等待比我在这里解释的时间更多的人......)

于 2012-04-17T15:17:22.457 回答
0

当您能够应用 XSLT 2.0 时,请使用以下内容:

<xsl:value-of select="distinct-values(dvm/rows/row/cell[3])"/>

在 XSLT 1.0 中,使用 Michael Kay 提到的 Muenchian 分组。一个示范:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:key name="Cells" match="dvm/rows/row/cell[3]" use="."/>
    <xsl:template match="/">
        <root>
            <w>
                <xsl:for-each select="dvm/rows/row/cell[3]">
                    <item>
                        <xsl:value-of select="."/>
                    </item>
                </xsl:for-each>
            </w>
            <z>
                <xsl:for-each select="dvm/rows/row/cell[3]">
                    <xsl:if test="generate-id() = generate-id(key('Cells', .)[1])">
                        <item>
                            <xsl:value-of select="."/>
                        </item>
                    </xsl:if>
                </xsl:for-each>
            </z>
        </root>
    </xsl:template>
</xsl:stylesheet>

这导致以下结果:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <w>
        <item>CODE1</item>
        <item>CODE1</item>
        <item>CODE2</item>
    </w>
    <z>
        <item>CODE1</item>
        <item>CODE2</item>
    </z>
</root>

说明:
xsl:key将键值分配给从match / use值构造的每个出现的节点 -cell[3]您希望关注的值。然后遍历所有这些cell[3]值,检查该值是否有一个唯一的 id(每个节点都有一个唯一的 id,可以通过应用generate-id()函数访问)等于节点集中具有相同键值的第一个元素的 id (这个集合是通过使用key()函数来选择的)。Cells实际上,当将当前节点值作为键值应用时,您正在检查处理的节点是否与键定义的节点集中的第一个节点相同。
实际上索引[1]是多余的,因为当它被忽略时,无论如何都会检查集合的第一个元素是否相等,因为generate-id(..node-set..)只会自动为节点集中的第一个节点生成一个id,但是添加索引会更整洁一些。
请注意,这会导致只选择一次出现的CODE1单元格 [3] 值。
一个实际的应用可能是定义一个xsl:variable内容等于<z>上面元素的内容(因此,xsl:for-each等等),然后使用该变量循环遍历其中的<item>元素并在您正在谈论的列表中显示它们。

于 2012-04-17T14:36:21.877 回答