使用XSLT 1.0过滤,分组,计数和选择XML中的特定节点 [英] Filtering, Grouping, Counting and Selecting specific nodes in XML using XSLT 1.0

查看:93
本文介绍了使用XSLT 1.0过滤,分组,计数和选择XML中的特定节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些看起来像这样的XML.

I've got some XML that looks a little like this.

<Dealer>
  <Vehicle>
    <Model>KA</Model>
    <Series>Type A</Series>
    <Price>1000.00</Price>
  </Vehicle>
  <Vehicle>
    <Model>KA</Model>
    <Series>Type C</Series>
    <Price>1400.00</Price>
  </Vehicle>
  <Vehicle>
    <Model>KA</Model>
    <Series>Type A</Series>
    <Price>1100.00</Price>
  </Vehicle>
  <Vehicle>
    <Model>FOCUS</Model>
    <Series>Type B</Series>
    <Price>5000.00</Price>
  </Vehicle>
  <Vehicle>
    <Model>FIESTA</Model>
    <Series>Type A</Series>
    <Price>6000.00</Price>
  </Vehicle>
</Dealer>

我想做的是选择一个特定的模型(例如:KA),然后将Series分组到一个不同的列表中(没有重复项),计算Series中有多少,但仅使用XSLT 1.0显示最便宜的

What I'm trying to do is select 1 specific Model (EG: KA) then group Series into a distinct list (no duplicates), count how many there are within the Series, but only display the cheapest, using XSLT 1.0.

EG.我的输出看起来像这样:

EG. My out put would look something like this:

KA Type A 2 in stock starting from 1000.00
KA Type C 1 in stock starting from 1400.00  

我一直在研究Muenchian分组方法,但是似乎无法将其与我要实现的其他目标结合起来.

I've been looking at the Muenchian Method of grouping, but can't seem to marry it up with the other things I'm trying to achieve.

这是我在下面的尝试.我的想法是只显示每个组中的第一项,即IE.最便宜的,并且以某种方式对每个组进行计数.

This is my attempt below. My thinking was to then just display the first item in each group, IE. the cheapest, and somehow do a count of each group.

<xsl:strip-space elements="*"/>

<xsl:template match="/Dealer">
   <xsl:apply-templates select="Vehicle[Model = 'KA']"/>
</xsl:template>

<xsl:key name="fSeries" match="Vehicle" use="Series" />
<xsl:template match="Vehicle">
   <xsl:for-each select="Vehicle[count(. | key('fSeries', Series)[1]) = 1]">
      <xsl:sort select="Price" />   
      <xsl:for-each select="key('fSeries', Series)">
         <xsl:sort select="Price" />
         <xsl:value-of select="Model" />&#32;<xsl:value-of select="Series" />&#32;<xsl:value-of select="Price" /><br />
      </xsl:for-each>
   </xsl:for-each>
</xsl:template> 

任何帮助都将非常有用.谢谢.

Would be very great of any help. Thanks.

推荐答案

您遇到了几个问题,第一个问题是Vehicle不是Vehicle的子对象-因此从上下文中调用<xsl:for-each select="Vehicle...">匹配Vehicle的模板将无法完成任何操作.

You have several problems, the first of them being the fact that Vehicle is not a child of Vehicle - so calling <xsl:for-each select="Vehicle..."> from the context of a template matching Vehicle will not accomplish anything.

另一件事是,您的钥匙与系列中的所有车辆都匹配,而与型号无关.

The other thing is that your key matches all vehicles in a series, regardless of model.

尝试一下:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:key name="vehicle-by-series" match="Vehicle[Model='KA']" use="Series" />

<xsl:template match="/Dealer">
    <xsl:for-each select="Vehicle[Model='KA'][count(. | key('vehicle-by-series', Series)[1]) = 1]">
        <xsl:value-of select="Model"/>
        <xsl:text>: </xsl:text>
        <xsl:value-of select="Series"/>
        <xsl:text>, </xsl:text>
        <xsl:variable name="grp" select="key('vehicle-by-series', Series)" />
        <xsl:value-of select="count($grp)"/>
        <xsl:text> in stock, starting from </xsl:text>
        <xsl:for-each select="$grp">
            <xsl:sort select="Price" data-type="number" order="ascending"/>
            <xsl:if test="position() = 1">
                <xsl:value-of select="Price"/>
            </xsl:if>
        </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

这篇关于使用XSLT 1.0过滤,分组,计数和选择XML中的特定节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆