XPath 3.x - 排序功能

时间:2018-03-29 15:30:31

标签: xml xpath xpath-3.0

我需要使用普通的XPath 3.0对一系列元素进行排序,因此没有XQuery,没有XSL-T,也没有代码。我试过跟this answer on how to use the sort function,但我不是XPath的专家,所以我无法弄清楚如何使用它。

所以,我的文档基本上有以下结构:

<?xml version="1.0" encoding="UTF-8"?>
<AppointmentList>
    <Appointment id="11" creatorID="1" creationDate="2018-03-01" reschedulable="ja" appointmentSeries="ja">
        <Start date="2018-03-14" time="12:00:00"/>
        <End date="2018-03-14" time="13:30:00"/>
        <Description>Vorführung</Description>
    </Appointment>

    <Appointment id="22" creatorID="2" creationDate="2018-02-14" reschedulable="ja" appointmentSeries="nein">
        <Start date="2018-03-20" time="13:00:00"/>
        <End date="2018-03-20" time="14:00:00"/>        
        <Description>Programm Meeting</Description>
        <Benachrichtigung art="EMail"/>
    </Appointment>

    <Appointment id="33" creatorID="3" creationDate="2018-02-23" reschedulable="nein" appointmentSeries="ja">
        <Start date="2018-02-24" time="15:00:00"/>
        <End date="2018-02-24" time="16:00:00"/>        
        <Description>Burglary Report</Description>
        <Benachrichtigung art="Beep"/>
    </Appointment>

    <Appointment id="44" creatorID="1" creationDate="2018-01-01" reschedulable="nein" appointmentSeries="nein">
        <Start date="2018-05-01" time="10:00:00"/>
        <End date="2018-05-01" time="17:00:00"/>        
        <Description>Besprechung Ministerium</Description>
    </Appointment>

    <Appointment id="55" creatorID="8" creationDate="2018-02-28" reschedulable="nein" appointmentSeries="nein">
        <Start date="2018-06-08" time="08:00:00"/>
        <End date="2018-06-09" time="18:00:00"/>        
        <Description>Spam Konferenz</Description>
    </Appointment>

    <Appointment id="66" creatorID="10" creationDate="2018-03-22" reschedulable="nein" appointmentSeries="nein">
        <Start date="2018-05-07" time="08:00:00"/>
        <End date="2018-05-07" time="18:00:00"/>        
        <Description>XML Tutorium</Description>
    </Appointment>

    <Appointment id="77" creatorID="9" creationDate="2018-03-15" reschedulable="ja" appointmentSeries="nein">
        <Start date="2018-04-20" time="08:00:00"/>
        <End date="2018-04-20" time="09:00:00"/>        
        <Description>Abschlussprüfung</Description>
    </Appointment>

    <Appointment id="88" creatorID="7" creationDate="2018-03-09" reschedulable="nein" appointmentSeries="ja">
        <Start date="2018-03-14" time="17:00:00"/>
        <End date="2018-03-14" time="18:00:00"/>        
        <Description>Versammlung Workaholics</Description>
    </Appointment>

    <Appointment id="99" creatorID="6" creationDate="2018-02-01" reschedulable="nein" appointmentSeries="nein">
        <Start date="2018-02-28" time="10:00:00"/>
        <End date="2018-02-28" time="17:00:00"/>        
        <Description>Fortbildung Datenbanken</Description>
    </Appointment>
</AppointmentList>

我希望按照日期升序排序下三个约会。因此,从现在开始的下一个约会是在结果序列的第一个位置,并且从第3个最近的日期开始的约会应该是序列的最后一个元素。下面显示的查询为我提供了尚未进行的约会,但我无法弄清楚如何正确应用排序功能。

/AppointmentList/Appointment[fn:dateTime(Start/@date, Start/@time) > fn:current-dateTime()]

谢谢,因为我还没有找到关于fn:sort函数的任何好文档。

1 个答案:

答案 0 :(得分:4)

函数fn:sort(...)存在三个版本,最多包含三个参数:

  1. $input as item()*:输入序列,
  2. $collation as xs:string?:用于字符串比较的归类(或空序列),
  3. $key as function(item()) as xs:anyAtomicType*) as item()*功能项,用于从要排序的项目中提取排序键(即应比较的部分)。
  4. 由于您不想对字符串进行排序,因此第二个参数应为()

    您案例中的排序键是每次约会的开始日期和时间。因此,您需要提供一个函数项,在给定Appointment节点的情况下,返回其开始日期的xs:dateTimefunction($app) { fn:dateTime($app/Start/@date, $app/Start/@time) }

    把所有东西放在一起:

    subsequence(
      sort(
        /AppointmentList/Appointment[fn:dateTime(Start/@date, Start/@time) > fn:current-dateTime()],
        (),
        function($app) { fn:dateTime($app/Start/@date, $app/Start/@time) }
      ),
      1,
      3
    )
    

    结果:

    <Appointment id="77" creatorID="9" creationDate="2018-03-15" reschedulable="ja" appointmentSeries="nein">
      <Start date="2018-04-20" time="08:00:00"/>
      <End date="2018-04-20" time="09:00:00"/>
      <Description>Abschlussprüfung</Description>
    </Appointment>
    <Appointment id="44" creatorID="1" creationDate="2018-01-01" reschedulable="nein" appointmentSeries="nein">
      <Start date="2018-05-01" time="10:00:00"/>
      <End date="2018-05-01" time="17:00:00"/>
      <Description>Besprechung Ministerium</Description>
    </Appointment>
    <Appointment id="66" creatorID="10" creationDate="2018-03-22" reschedulable="nein" appointmentSeries="nein">
      <Start date="2018-05-07" time="08:00:00"/>
      <End date="2018-05-07" time="18:00:00"/>
      <Description>XML Tutorium</Description>
    </Appointment>