XSL:将节点值与另一个节点进行比较

时间:2012-04-17 14:29:59

标签: xslt

我对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>

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分: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等),然后使用该变量循环遍历{ {1}}中的元素,并在您所说的列表中显示这些元素。