Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml XSL:仅提取前5个匹配值,并进行排序_Xml_Xslt - Fatal编程技术网

Xml XSL:仅提取前5个匹配值,并进行排序

Xml XSL:仅提取前5个匹配值,并进行排序,xml,xslt,Xml,Xslt,我有5个电台需要填补。此XML输出等待的来宾,最新的在底部。我需要增加XML,填充5个站点中的每一个。基本上,您可以按transactionID将它们分成多个组,然后自下而上读取文件,查看每个组的顶部位置。如果我们还没有填满VirtualDisplayId插槽,它们就会被插入 您将看到,我们将事务分组为7773324,最上面的条目是Justin K02084,因此他获得Id 101。然后是下一个分组(7773323),Andy2084的顶部条目也是ID101,Justin刚刚填充了它,所以这里是

我有5个电台需要填补。此XML输出等待的来宾,最新的在底部。我需要增加XML,填充5个站点中的每一个。基本上,您可以按transactionID将它们分成多个组,然后自下而上读取文件,查看每个组的顶部位置。如果我们还没有填满VirtualDisplayId插槽,它们就会被插入

您将看到,我们将事务分组为7773324,最上面的条目是Justin K02084,因此他获得Id 101。然后是下一个分组(7773323),Andy2084的顶部条目也是ID101,Justin刚刚填充了它,所以这里是我的XSLT崩溃的地方。我把Andyk2084带到101,我需要跳过他,下一个条目应该是Andy2083,因为他的交易的顶部条目是201,我还没有填写,所以他得到201。该逻辑应重复,直到所有5个插槽都填满为止

我的另一个问题是,我似乎不知道如何只填补5个空缺。我的XSL一直在运行:)这是我写过的最棘手的XSL,所以我终于屈服了,我问是否有人能给我一些提示

到目前为止,我的输出:

<table>
   <tr><td>JUSTIN K2084</td><td>101</td></tr>
   <tr><td>ANDY K2084</td><td>101</td></tr>
   <tr><td>ANDY K2083</td><td>201</td></tr>
   <tr><td>ANDY K2082</td><td>301</td></tr>
   <tr><td>ANDY K2081</td><td>401</td></tr>
   <tr><td>ANDY K2080</td><td>501</td></tr>
   <tr><td>ANDY K2079</td><td>101</td></tr>...[LOOPS THROUGH ENTIRE FILE]
</table>

贾斯汀K2084101
安迪K2084101
安迪K2083201
安迪K2082301
安迪K2081401
安迪K2080501
ANDY K2079101…[循环浏览整个文件]
期望输出:

<table>
    <tr><td>JUSTIN K2084</td><td>101</td></tr>
    <tr><td>ANDY K2083</td><td>201</td></tr>
    <tr><td>ANDY K2082</td><td>301</td></tr>
    <tr><td>ANDY K2081</td><td>401</td></tr>
    <tr><td>ANDY K2080</td><td>501</td></tr>
</table>

贾斯汀K2084101
安迪K2083201
安迪K2082301
安迪K2081401
安迪K2080501
XSL:


XML:


7773317
200
安迪K2078
7773318
100
安迪K2079
7773319
501
安迪K2080
7773319
401
安迪K2080
7773319
301
安迪K2080
7773319
201
安迪K2080
7773319
101
安迪K2080
7773320
401
安迪K2081
7773320
501
安迪K2081
7773320
301
安迪K2081
7773320
201
安迪K2081
7773320
101
安迪K2081
7773321
301
安迪K2082
7773321
501
安迪K2082
7773321
401
安迪K2082
7773321
201
安迪K2082
7773321
101
安迪K2082
7773322
201
安迪K2083
7773322
501
安迪K2083
7773322
401
安迪K2083
7773322
301
安迪K2083
7773322
101
安迪K2083
7773323
101
安迪K2084
7773323
501
安迪K2084
7773323
401
安迪K2084
7773323
301
安迪K2084
7773323
201
安迪K2084
7773324
101
贾斯汀K2084
7773324
501
贾斯汀K2084
7773324
401
贾斯汀K2084
7773324
301
贾斯汀K2084
7773324
201
贾斯汀K2084
这就是你需要的吗

<xsl:template match="/table">
  <xsl:variable name="table" select="." />
  <xsl:for-each select="distinct-values(tr/td[2])">
    <xsl:variable name="group" select="."/>
    <xsl:copy-of select="$table/tr[td[2][text()=$group]][1]"/>
  </xsl:for-each>
</xsl:template>

小提琴:这就是你需要的吗

<xsl:template match="/table">
  <xsl:variable name="table" select="." />
  <xsl:for-each select="distinct-values(tr/td[2])">
    <xsl:variable name="group" select="."/>
    <xsl:copy-of select="$table/tr[td[2][text()=$group]][1]"/>
  </xsl:for-each>
</xsl:template>

Fiddle:

您当前的代码很接近,但它的输出并不是您所需要的。让我们更详细地看一下

分解你的代码 每个 这对性能或输出没有太大影响,但似乎不适合您的环境

<xsl:for-each select="SpeedOfService">
如果您的实际工作输入XML文件有多个
SpeedOfService
元素,我建议使用
,然后创建一个单独的
模板

每组的第一个
这是下一个事情稍微偏离轨道的地方

每组的第二个
如果 这似乎是试图将输出限制为该组中的第一组元素。与此相反:

<xsl:for-each-group select="current-group()" group-by="VirtualDisplayId">
    <xsl:if test="position()=1">
。。。但我们已经确定,通过
VirtualDisplayId
进行分组并没有任何作用。最终,在省略每个组的第二个
if
后,代码输出相同的一组八行表:

<xsl:for-each-group select="ServiceTiming" group-by="TransactionNumber">
    <xsl:sort select="position()" data-type="number" order="descending"/>
    <tr><td><xsl:value-of select="current-group()[1]/TableName"/></td><td><xsl:value-of select="current-group()[1]/VirtualDisplayId"/></td></tr>
</xsl:for-each-group>
输出:

  <tr>
     <td>JUSTIN K2084</td>
     <td>101</td>
  </tr>
  <tr>
     <td>ANDY K2084</td>
     <td>101</td>
  </tr>
  <tr>
     <td>ANDY K2083</td>
     <td>201</td>
  </tr>
  <tr>
     <td>ANDY K2082</td>
     <td>301</td>
  </tr>
  <tr>
     <td>ANDY K2081</td>
     <td>401</td>
  </tr>
  <tr>
     <td>ANDY K2080</td>
     <td>501</td>
  </tr>
  <tr>
     <td>ANDY K2079</td>
     <td>100</td>
  </tr>
  <tr>
     <td>ANDY K2078</td>
     <td>200</td>
  </tr>
尽管这只输出了五行表,但值仍然不是我们想要的——我们仍然有两行的
VirtualDisplayId
值为
101

另一种方法 那么,我们如何首先通过
TransactionNumber
进行分组,然后通过
VirtualDisplayId
进行第二次分组,但第二次分组知道第一次分组

一种方法是将第一次分组的结果存储在一个变量中:我们在上面得到的八个表行

<xsl:variable name="First_Group">
    <xsl:for-each-group select="ServiceTiming" group-by="TransactionNumber">
        <xsl:sort select="position()" data-type="number" order="descending"/>
        <tr><td><xsl:value-of select="./TableName"/></td><td><xsl:value-of select="./VirtualDisplayId"/></td></tr>
    </xsl:for-each-group>
</xsl:variable>
为了将表输出限制在前五行,我们现在添加
if
语句来检查位置:

<xsl:for-each-group select="$First_Group/tr" group-by="td[2]">
    <xsl:if test="position() &lt; 6">
        <xsl:copy-of select="."/>
    </xsl:if>
</xsl:for-each-group>

我们得到了我们想要的输出:

<table>
    <tr>
        <td>JUSTIN K2084</td>
        <td>101</td>
    </tr>
    <tr>
        <td>ANDY K2083</td>
        <td>201</td>
    </tr>
    <tr>
        <td>ANDY K2082</td>
        <td>301</td>
    </tr>
    <tr>
        <td>ANDY K2081</td>
        <td>401</td>
    </tr>
    <tr>
        <td>ANDY K2080</td>
        <td>501</td>
    </tr>
</table

贾斯汀K2084
101
安迪K2083
201
安迪K2082
301
安迪K2081
401
安迪K2080
501
您当前的代码很接近,但是它的输出并不是您所需要的。让我们更详细地看一下

分解你的代码 每个
这对性能或输出没有太大影响,但似乎不适合您的环境

<xsl:for-each select="SpeedOfService">
如果您的实际工作输入XML文件有多个
SpeedOfService
元素,我建议使用
,然后创建一个单独的
模板

每组的第一个
这是下一个事情稍微偏离轨道的地方

每组的第二个
如果
这似乎是试图将输出限制为该组中的第一组元素。与此相反:

<xsl:for-each-group select="current-group()" group-by="VirtualDisplayId">
    <xsl:if test="position()=1">
。。
<xsl:for-each-group select="ServiceTiming" group-by="TransactionNumber">
    <xsl:sort select="position()" data-type="number" order="descending"/>
    <tr><td><xsl:value-of select="current-group()[1]/TableName"/></td><td><xsl:value-of select="current-group()[1]/VirtualDisplayId"/></td></tr>
</xsl:for-each-group>
<xsl:for-each-group select="ServiceTiming" group-by="TransactionNumber">
    <xsl:sort select="position()" data-type="number" order="descending"/>
    <tr><td><xsl:value-of select="./TableName"/></td><td><xsl:value-of select="./VirtualDisplayId"/></td></tr>
</xsl:for-each-group>
  <tr>
     <td>JUSTIN K2084</td>
     <td>101</td>
  </tr>
  <tr>
     <td>ANDY K2084</td>
     <td>101</td>
  </tr>
  <tr>
     <td>ANDY K2083</td>
     <td>201</td>
  </tr>
  <tr>
     <td>ANDY K2082</td>
     <td>301</td>
  </tr>
  <tr>
     <td>ANDY K2081</td>
     <td>401</td>
  </tr>
  <tr>
     <td>ANDY K2080</td>
     <td>501</td>
  </tr>
  <tr>
     <td>ANDY K2079</td>
     <td>100</td>
  </tr>
  <tr>
     <td>ANDY K2078</td>
     <td>200</td>
  </tr>
<xsl:if test="position() &lt; 6">
    <tr><td><xsl:value-of select="./TableName"/></td><td><xsl:value-of select="./VirtualDisplayId"/></td></tr>
</xsl:if>
<xsl:variable name="First_Group">
    <xsl:for-each-group select="ServiceTiming" group-by="TransactionNumber">
        <xsl:sort select="position()" data-type="number" order="descending"/>
        <tr><td><xsl:value-of select="./TableName"/></td><td><xsl:value-of select="./VirtualDisplayId"/></td></tr>
    </xsl:for-each-group>
</xsl:variable>
<xsl:for-each-group select="$First_Group/tr" group-by="td[2]">
    <xsl:copy-of select="."/>
</xsl:for-each-group>
<table>
    <tr>
        <td>JUSTIN K2084</td>
        <td>101</td>
    </tr>
    <tr>
        <td>ANDY K2083</td>
        <td>201</td>
    </tr>
    <tr>
        <td>ANDY K2082</td>
        <td>301</td>
    </tr>
    <tr>
        <td>ANDY K2081</td>
        <td>401</td>
    </tr>
    <tr>
        <td>ANDY K2080</td>
        <td>501</td>
    </tr>
    <tr>
        <td>ANDY K2079</td>
        <td>100</td>
    </tr>
    <tr>
        <td>ANDY K2078</td>
        <td>200</td>
    </tr>
</table
<xsl:for-each-group select="$First_Group/tr" group-by="td[2]">
    <xsl:if test="position() &lt; 6">
        <xsl:copy-of select="."/>
    </xsl:if>
</xsl:for-each-group>
<table>
    <tr>
        <td>JUSTIN K2084</td>
        <td>101</td>
    </tr>
    <tr>
        <td>ANDY K2083</td>
        <td>201</td>
    </tr>
    <tr>
        <td>ANDY K2082</td>
        <td>301</td>
    </tr>
    <tr>
        <td>ANDY K2081</td>
        <td>401</td>
    </tr>
    <tr>
        <td>ANDY K2080</td>
        <td>501</td>
    </tr>
</table
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">
    <xsl:output method="html" version="4.0" indent="yes"/>

    <xsl:template match="/SpeedOfService">
        <table>
            <xsl:variable name="First_Group">
                <xsl:for-each-group select="ServiceTiming" group-by="TransactionNumber">
                    <xsl:sort select="position()" data-type="number" order="descending"/>
                    <tr><td><xsl:value-of select="./TableName"/></td><td><xsl:value-of select="./VirtualDisplayId"/></td></tr>
                </xsl:for-each-group>
            </xsl:variable>
            <xsl:for-each-group select="$First_Group/tr" group-by="td[2]">
                <xsl:if test="position() &lt; 6">
                    <xsl:copy-of select="."/>
                </xsl:if>
            </xsl:for-each-group>
        </table>
    </xsl:template>
</xsl:stylesheet>