【问题标题】:How to compare siblings from the same group?如何比较同一组的兄弟姐妹?
【发布时间】:2019-09-08 23:44:01
【问题描述】:

我有一段代码如下所示:

<root>
   <applicant>
     <id>XYZ</id>
     <group>
        <start_date>2019-04-01</start_date>
        <end_date>2019-04-01</end_date>
     </group>
     <group>
        <start_date>2019-04-02</start_date>
        <end_date>2019-04-02</end_date>
     </group>
     <group>
        <start_date>2019-04-03</start_date>
        <end_date>2019-04-03</end_date>
     </group>
  </applicant>
  <applicant>
     <id>ABC</id>
     <group>
        <start_date>2019-05-01</start_date>
        <end_date>2019-05-01</end_date>
     </group>
     <group>
        <start_date>2019-05-02</start_date>
        <end_date>2019-05-02</end_date>
     </group>
     <group>
        <start_date>2019-05-03</start_date>
        <end_date>2019-05-03</end_date>
     </group>
  </applicant>
</root>

如果来自下一个兄弟姐妹的日期相差 1 天(天数差异为 1),我需要按申请人对其进行分组并合并到一个具有单个开始日期和结束日期的节点中

所以上面的代码实现如下:

<root>
  <applicant>
    <id>XYZ</id>
    <start_date>2019-04-01</start_date>
    <end_date>2019-04-03</end_date>
  </applicant>
  <applicant>
    <id>ABC</id>
    <start_date>2019-05-01</start_date>
    <end_date>2019-05-03</end_date>
  </applicant>
</root>

我正在考虑使用 following-sibling:: 或某种重复。

【问题讨论】:

  • 如果您确实可以使用 XSLT 2.0 或 3.0,那么我会从问题中删除 XSLT-1.0 标记,以具体说明您可以使用什么版本(特别是因为任何 XSLT 1.0 解决方案都不会很容易)。谢谢!

标签: xslt xslt-2.0 xslt-grouping xslt-3.0


【解决方案1】:

假设您确实可以使用 XSLT 2.0 或更高版本,您可以在此处使用 xsl:for-each-group,并从 start_date - 1 与前一组的 end_date 不匹配的元素开始分组。

试试这个 XSLT

<xsl:stylesheet 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     exclude-result-prefixes="xs"
     version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="xml" indent="yes" />

  <xsl:template match="applicant">
    <xsl:copy>
      <xsl:copy-of select="id" />
      <xsl:for-each-group select="group" group-starting-with="group[not(xs:date(start_date) - xs:dayTimeDuration('P1D') = xs:date(preceding-sibling::group[1]/end_date))]">
        <group>
          <xsl:copy-of select="start_date, current-group()[last()]/end_date" />
        </group>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

(这使用 XSLT 3.0。在 XSLT 2.0 中,您需要做的就是用身份模板替换 xsl:mode

【讨论】:

  • 很好的答案。我认为应该说一下使用这种特殊条件以避免第一个不匹配组。
猜你喜欢
  • 2014-07-12
  • 1970-01-01
  • 2019-05-06
  • 2019-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-23
相关资源
最近更新 更多