Как сравнить братьев и сестер из той же группы? - PullRequest
0 голосов
/ 18 апреля 2019

У меня есть кусок кода, который выглядит следующим образом:

<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>

Я думал о том, чтобы использовать следующего родного брата :: или какое-то повторение.

1 Ответ

1 голос
/ 18 апреля 2019

Если вы действительно можете использовать 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 шаблоном идентификации)

...