Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.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
Xslt 在同一时间优先级内对节点进行分组_Xslt - Fatal编程技术网

Xslt 在同一时间优先级内对节点进行分组

Xslt 在同一时间优先级内对节点进行分组,xslt,Xslt,这是我的实际数据(gps跟踪点)的简化版本。 我有一个按升序排列的时间列表 <gpx> <trk> <trkseg> <trkpt> <time>2000-01-01T15:25:00Z</time> </trkpt> <trkpt> <

这是我的实际数据(gps跟踪点)的简化版本。 我有一个按升序排列的时间列表

<gpx>
    <trk>
        <trkseg>
            <trkpt>
                <time>2000-01-01T15:25:00Z</time>
            </trkpt>
            <trkpt>
                <time>2000-01-01T15:26:00Z</time>
            </trkpt>
            <trkpt>
                <time>2000-01-01T15:27:00Z</time>
            </trkpt>
        </trkseg>
    </trk>
    <trk>
        <trkseg>
            <trkpt>
                <time>2000-01-01T15:28:00Z</time>
            </trkpt>
            <trkpt>
                <time>2000-01-01T15:29:00Z</time>
            </trkpt>            
        </trkseg>
        <trkseg>
            <trkpt>
                <time>2000-01-01T16:00:00Z</time>
            </trkpt>
            <trkpt>
                <time>2000-01-01T16:01:00Z</time>
            </trkpt>            
        </trkseg>
    </trk>
</gpx>

2000-01-01T15:25:00Z
2000-01-01T15:26:00Z
2000-01-01T15:27:00Z
2000-01-01T15:28:00Z
2000-01-01T15:29:00Z
2000-01-01T16:00:00Z
2000-01-01T16:01:00Z
我想检测“停止”并将连续的时间分组。 例如,“停止”表示5分钟或更长时间内没有数据,我会

<gpx >
    <trk>
        <trkseg>
            <trkpt>
                <time>2000-01-01T15:25:00Z</time>
            </trkpt>
            <trkpt>
                <time>2000-01-01T15:26:00Z</time>
            </trkpt>
            <trkpt>
                <time>2000-01-01T15:27:00Z</time>
            </trkpt>
            <trkpt>
                <time>2000-01-01T15:28:00Z</time>
            </trkpt>
            <trkpt>
                <time>2000-01-01T15:29:00Z</time>
            </trkpt>    
        </trkseg>
    </trk>
    <trk>
        <trkseg>
            <trkpt>
                <time>2000-01-01T16:00:00Z</time>
            </trkpt>
            <trkpt>
                <time>2000-01-01T16:01:00Z</time>
            </trkpt>            
        </trkseg>
    </trk>
</gpx>

2000-01-01T15:25:00Z
2000-01-01T15:26:00Z
2000-01-01T15:27:00Z
2000-01-01T15:28:00Z
2000-01-01T15:29:00Z
2000-01-01T16:00:00Z
2000-01-01T16:01:00Z

这是XQuery 3.0/3.1中一个很好的子句用例:

declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:indent "yes";

<gpx>
{
let $dateTimes := //time/xs:dateTime(.),
    $stopDuration := xs:dayTimeDuration('PT5M')
for tumbling window $w in $dateTimes
start when true()
end $e next $n when $n - $e gt $stopDuration
return
  <trk>
    <trkseg>
    {
      $w!<trkpt><time>{.}</time></trkpt>
    }    
    </trkseg>
  </trk>
}
</gpx>
如果需要在XSLT2.0中执行此操作,一种方法是编写一个函数,该函数逐项递归处理dateTime序列,并在发现dateTime的差异大于允许的限制时分别返回一个组
trk
元素(因此基本上实现了XQuery检查
end$e next$n when$n-$e gt$stopDuration
):



谢谢。有人对XPath有想法吗?嗯,我目前的处理器支持xslt 2.0(altova 2010)…因此我知道我应该开始考虑更新我的系统。谢谢@Martin!请说明您的xslt版本和处理器。
<?xml version="1.0" encoding="UTF-8"?>
<gpx>
   <trk>
      <trkseg>
         <trkpt>
            <time>2000-01-01T15:25:00Z</time>
         </trkpt>
         <trkpt>
            <time>2000-01-01T15:26:00Z</time>
         </trkpt>
         <trkpt>
            <time>2000-01-01T15:27:00Z</time>
         </trkpt>
         <trkpt>
            <time>2000-01-01T15:28:00Z</time>
         </trkpt>
         <trkpt>
            <time>2000-01-01T15:29:00Z</time>
         </trkpt>
      </trkseg>
   </trk>
   <trk>
      <trkseg>
         <trkpt>
            <time>2000-01-01T16:00:00Z</time>
         </trkpt>
         <trkpt>
            <time>2000-01-01T16:01:00Z</time>
         </trkpt>
      </trkseg>
   </trk>
</gpx>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="xs math mf"
    expand-text="yes"
    version="3.0">

    <xsl:variable name="stop" as="xs:dayTimeDuration" select="xs:dayTimeDuration('PT5M')"/>

    <xsl:output indent="yes"/>

    <xsl:function name="mf:wrap" as="element(trk)">
        <xsl:param name="dateTimes" as="xs:dateTime*"/>
        <trk>
            <trkseq>
                <xsl:for-each select="$dateTimes">
                    <trkpt>
                        <time>
                            <xsl:value-of select="."/>
                        </time>
                    </trkpt>
                </xsl:for-each>
            </trkseq>
        </trk>
    </xsl:function>

    <xsl:template match="gpx">
        <xsl:copy>
            <xsl:variable name="dateTimes" as="xs:dateTime*" select=".//time/xs:dateTime(.)"/>
            <xsl:iterate select="$dateTimes">
                <xsl:param name="w" as="xs:dateTime*" select="()"/>
                <xsl:param name="e" as="xs:dateTime?" select="()"/>
                <xsl:on-completion>
                    <xsl:sequence select="mf:wrap($w)"/>
                </xsl:on-completion>
                <xsl:variable name="n" as="xs:dateTime" select="."/>
                <xsl:choose>
                    <xsl:when test="exists($e) and exists($n) and $n - $e gt $stop">
                        <xsl:sequence select="mf:wrap($w)"/>
                        <xsl:next-iteration>
                            <xsl:with-param name="w" select="$n"/>
                            <xsl:with-param name="e" select="$n"/>
                        </xsl:next-iteration>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:next-iteration>
                            <xsl:with-param name="w" select="$w, $n"/>
                            <xsl:with-param name="e" select="$n"/>
                        </xsl:next-iteration>
                    </xsl:otherwise>
                </xsl:choose>            
            </xsl:iterate>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="xs mf" version="2.0">

    <xsl:param name="stop" as="xs:dayTimeDuration" select="xs:dayTimeDuration('PT5M')"/>

    <xsl:output indent="yes"/>

    <xsl:function name="mf:group" as="element(trk)*">
        <xsl:param name="dateTimes" as="xs:dateTime*"/>
        <xsl:param name="stop" as="xs:dayTimeDuration"/>
        <xsl:sequence select="mf:group($dateTimes[1], $dateTimes[position() gt 1], $stop)"/>
    </xsl:function>

    <xsl:function name="mf:group" as="element(trk)*">
        <xsl:param name="group" as="xs:dateTime*"/>
        <xsl:param name="dateTimes" as="xs:dateTime*"/>
        <xsl:param name="stop" as="xs:dayTimeDuration"/>
        <xsl:variable name="next" as="xs:dateTime?" select="$dateTimes[1]"/>
        <xsl:variable name="end" as="xs:dateTime" select="$group[last()]"/>
        <xsl:choose>
            <xsl:when test="not(exists($next))">
                <xsl:sequence select="mf:wrap($group)"/>
            </xsl:when>
            <xsl:when test="$next - $end gt $stop">
                <xsl:sequence select="mf:wrap($group)"/>
                <xsl:sequence select="mf:group($next, $dateTimes[position() gt 1], $stop)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:sequence select="mf:group(($group, $next), $dateTimes[position() gt 1], $stop)"
                />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>

    <xsl:function name="mf:wrap" as="element(trk)">
        <xsl:param name="dateTimes" as="xs:dateTime*"/>
        <trk>
            <trkseq>
                <xsl:for-each select="$dateTimes">
                    <trkpt>
                        <time>
                            <xsl:value-of select="."/>
                        </time>
                    </trkpt>
                </xsl:for-each>
            </trkseq>
        </trk>
    </xsl:function>

    <xsl:template match="gpx">
        <xsl:copy>
            <xsl:sequence select="mf:group(.//time/xs:dateTime(.), $stop)"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>