xml - XSLT - 比赛和分组时间
问题描述
我正在尝试根据下面的 XML 创建一些时间表。这是模拟数据,因此请忽略时间上的巨大差距。本质上,当日期代码与 0 匹配时,如下所示,我需要仅在午夜 (00:00) 之后提取所有值并丢弃其余值并增加日期 + 1。但是,如果进出时间在午夜重叠,例如下面示例中的 1755-0115,那么我仍然需要在文件中获取同一天的时间,但是将 1755 硬编码为 00:01 并且仍然增加一天。午夜之前的所有其他东西仍然被丢弃。所有区块总是有序的,最早的出拳(例如 0900)是早上出拳。
`<Employee>
<employee_id>123456</employee_id>
<day_code>0</day_code>
<day>12-01-18</day>
<block>
<in>0900</in>
<out>1526</out>
</block>
<block>
<in>1526</in>
<out>1526</out>
</block>
<block>
<in>1526</in>
<out>1740</out>
</block>
<block>
<in>1740</in>
<out>1755</out>
</block>
<block>
<in>1755</in>
<out>0115</out>
</block>
<block>
<in>0115</in>
<out>0315</out>
</block>
</Employee>`
因此,当我提取数据时,我需要它看起来像这样。
'<Employee_Schedules>
<in>12-02-18-T00:01</in>
<out>12-02-18-T01:15</out>
<block>
<in>12-02-18-T01:15</in>
<out>12-02-18-T03:15</out>
</block>
</Employee_Schedules>`
我正在考虑使用前面的兄弟函数检查两个块。检查第一个块的输入时间是否小于第二个块的输出时间输入,第二个条件是检查立即块的输入时间是否小于输出时间,但这不是很好。
任何帮助是极大的赞赏!
解决方案
我“修复”了day_code
使用 XSD/XPath的格式,yyyy-mm-dd
然后简单地编写了两个模板与第一个孩子中的模板进行比较in
或out
值:block
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output indent="yes"/>
<xsl:mode on-no-match="shallow-skip"/>
<xsl:template match="Employee[day_code = 0]">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="Employee[day_code = 0]/block[position() gt 1 and in > ../block[1]/in and out <= ../block[1]/in]">
<xsl:copy>
<xsl:variable name="date" as="xs:date" select="xs:date(../day)"/>
<xsl:variable name="new-date" as="xs:date" select="$date + xs:dayTimeDuration('P1D')"/>
<in>
<xsl:value-of select="dateTime($new-date, xs:time('00:01:00'))"/>
</in>
<out>
<xsl:value-of select="dateTime($new-date, xs:time(replace(out, '([0-9]{2})([0-9]{2})', '$1:$2:00')))"/>
</out>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="Employee[day_code = 0]/block[position() gt 1 and in <= ../block[1]/in]">
<xsl:copy>
<xsl:variable name="date" as="xs:date" select="xs:date(../day)"/>
<xsl:variable name="new-date" as="xs:date" select="$date + xs:dayTimeDuration('P1D')"/>
<in>
<xsl:value-of select="dateTime($new-date, xs:time(replace(in, '([0-9]{2})([0-9]{2})', '$1:$2:00')))"/>
</in>
<out>
<xsl:value-of select="dateTime($new-date, xs:time(replace(out, '([0-9]{2})([0-9]{2})', '$1:$2:00')))"/>
</out>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/94rmq5Z给出了结果
<Employee>
<block>
<in>2018-12-02T00:01:00</in>
<out>2018-12-02T01:15:00</out>
</block>
<block>
<in>2018-12-02T01:15:00</in>
<out>2018-12-02T03:15:00</out>
</block>
</Employee>
请注意,如果第一个块元素确实发生了更改,例如 has <in>0900</in>
but ,则确定应该发生什么<out>0700</out>
。
示例是 XSLT 3,但xsl:mode
声明的使用可以通过使用在 XSLT 2 中重写
<xsl:template match="@* | node()">
<xsl:apply-templates/>
</xsl:template>
推荐阅读
- c# - 有没有办法找出谁在运行时试图加载给定的程序集?
- c++ - LNK1104:无法打开 libpjproject-i386-Win32-vc14-Debug-Static.lib
- python - 如何重新组织熊猫数据框,以便将一列中的所有重复值压缩成一行,其中包含另一列中的所有信息?
- php - Asana/php-asana getTasks() 无效请求错误
- android - Android 构建变体多个应用程序
- python-3.x - 努力理解fbprophet库中交叉验证函数的参数
- java - Java - 正则表达式检查字符串是否包含连续数字以及其他字符
- python - 如何使用 pyinstaller 打包多文件夹 python 应用程序
- r - 如何从 R 下载 Yahoo Finance 的数据并将其保存到我的计算机?
- python-3.x - 如何计算python中两个日期时间值之间的差异?