0

我正在尝试生成一个可以与现有 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。

4

2 回答 2

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' 中排序。

于 2013-02-08T15:37:13.410 回答
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。此页面提供了有关在 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>
于 2013-02-08T14:19:05.643 回答