仅使用XML节点不同值填充下拉列表

时间:2013-02-08 13:46:49

标签: html xml xslt xpath xslt-grouping

我正在尝试生成一个可以使用现有XML数据文件的搜索过滤器,而我首先尝试从下拉列表框中的一个节点显示唯一值。

可以在...处看到XML文件的示例 http://kirk.rapweb.co.uk/testing/filter/tidy/plain/products.xml

我设法使用XSLT以更易读的格式显示XML ... http://kirk.rapweb.co.uk/testing/filter/tidy/products.xml

应用过滤器的相同数据... http://kirk.rapweb.co.uk/testing/filter/tidy/filter/products.xml

我希望在第一个下拉列表框中列出的值被过滤掉... http://kirk.rapweb.co.uk/testing/filter/tidy/distinct/products.xml

所有数据都被拉入HTML页面...... http://kirk.rapweb.co.uk/testing/filter/tidy/html/

我正在努力弄清楚如何从...获取数据 http://kirk.rapweb.co.uk/testing/filter/tidy/distinct/products.xml 进入HTML页面下拉列表框。

任何人都可以提供建议,指出正确的方向或确认我走在正确的轨道上吗?

我想要达到的最终结果是有2个下拉框。

下拉列表1将包含......刹车,排气,照明

下拉列表2将包含...

  • 如果先前选择了制动器......圆盘和鼓,垫和鞋。
  • 如果之前选择了排气......中心,后方。
  • 如果之前选择了照明......前照灯,后照灯。

现在我只想专注于使用上面讨论的数据填充下拉框1。

2 个答案:

答案 0 :(得分:1)

根据您更新的说明,您似乎想要创建一个包含不同组值的下拉列表。这是分组问题的一个例子,在XSLT 1.0中,这样做的方法是使用一种称为Muenchian分组的技术。它是这样的:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" omit-xml-declaration="yes"/>
  <xsl:key name="kGroup" match="product" use="group"/>

  <xsl:template match="/">
    <select name="productGroup" id="productGroup">
      <xsl:apply-templates 
        select="dataroot/product[generate-id() = 
                                 generate-id(key('kGroup', group)[1])]" />
    </select>
  </xsl:template>

  <xsl:template match="product">
    <option value="{group}">
      <xsl:value-of select="group"/>
    </option>
  </xsl:template>
</xsl:stylesheet>

在输入XML上运行时,会生成以下内容:

<select name="productGroup" id="productGroup">
  <option value="Brakes">Brakes</option>
  <option value="Exhaust">Exhaust</option>
  <option value="Lighting">Lighting</option>
</select>

然后,您将使用与现在使用相同的JavaScript将结果放入HTML DOM中的特定元素中,该元素可通过其ID轻松找到。

现在,对于下一步,一旦上述工作正常,您将在此下拉列表中放置一个JavaScript事件,以便在选择项目时运行另一个转换。您将获得此选定值,然后您可以将其作为参数值传递给另一个XSLT。 This page提供了有关在JavaScript中将参数传递到XSLT的良好信息。 XSLT看起来像这样(再次使用Muenchian分组):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" omit-xml-declaration="yes"/>
  <xsl:key name="kType" match="product" use="type"/>

  <xsl:param name="group" />

  <xsl:template match="/">
    <select name="productType" id="productType">
      <xsl:apply-templates 
        select="dataroot/product[generate-id() = 
                     generate-id(key('kType', type)[1])][group = $group]" />
    </select>
  </xsl:template>

  <xsl:template match="product">
    <option value="{type}">
      <xsl:value-of select="type"/>
    </option>
  </xsl:template>
</xsl:stylesheet>

当参数值“Lighting”作为group参数传入并且在输入XML上运行时,会产生:

<select name="productType" id="productType">
  <option value="Headlamps">Headlamps</option>
  <option value="Rear Lights">Rear Lights</option>
</select>

答案 1 :(得分:1)

我猜你假设你不知道数据中会有多少不同的“群组”(我的意思是,有人可以随时添加新群组,不是吗?)。

XSLT 1.0中用于分组元素的标准技术之一是“Muenchian Grouping”(XSLT 2.0实现本机分组函数和元素),它基于比较唯一ID。

在下面的解决方案中,我假设XML文档中的数据尚未分组。

<xsl:key name="group-key"
         match="product"
         use="group" />

<xsl:template match="dataroot"> 
    <select>
        <xsl:for-each select="product[generate-id(.) = generate-id(key('group-key', group)[1])]">
            <!-- We sort the group names alphabetically. If the names of the groups are already ordered alphabetically, the xsl:sort can be omitted. -->
            <xsl:sort select="group" />
            <option><xsl:value-of select="group" /></option>
        </xsl:for-each>
    </select>
</xsl:template>

将此模板(将xsl:stylesheet元素添加到原始'product.xml')的结果是:

<select>
    <option>Brakes</option>
    <option>Exhaust</option>
    <option>Lighting</option>
</select>

注意:即使我们删除'xsl:sort'元素,输出也是一样的,因为数据已在'product.xml'中排序。