【发布时间】:2018-01-10 20:30:13
【问题描述】:
当我尝试通过应用 XSLT 解析 XML 文件时,在获取不同值时无法跳过重复值。
这是包含原始值和列的 XML 文件,以 XML 格式显示数据
<Poll>
<SQLConnection>
<SQLCommand identifier="TIMEPUNCH">
<Data>
<Row sdt="12-03-2017 00:00:00" edt="12-03-2017 00:00:00" e="7" j="630" Expr1004="630" cin="11:07a" cout="1:24p" hrs_ovrday="0" hrs_ovrwk="2.6333" tips="23" sales=256" hrs_holida="0" rh="4.1833" total_pay="113.87"/>
<Row sdt="12-03-2017 00:00:00" edt="12-03-2017 00:00:00" e="7" j="630" Expr1004="630" cin="6:04a" cout="10:36a" hrs_ovrday="0" hrs_ovrwk="2.6333" tips="0" sales="0" hrs_holida="0" rh="4.1833" total_pay="113.87"/>
<Row sdt="12-03-2017 00:00:00" edt="12-03-2017 00:00:00" e="71" j="400" Expr1004="400" cin="12:05p" cout="3:18p" hrs_ovrday="0" hrs_ovrwk="0" tips="47.59" sales="357.61" hrs_holida="0" rh="7.5" total_pay="78.75"/>
<Row sdt="12-03-2017 00:00:00" edt="12-03-2017 00:00:00" e="71" j="500" Expr1004="500" cin="4:07p" cout="8:24p" hrs_ovrday="0" hrs_ovrwk="0" tips="47.59" sales="357.61" hrs_holida="0" rh="7.5" total_pay="78.75"/>
</Data>
</SQLCommand>
</SQLConnection>
</Poll>
通过使用此 XSLT,我无法将上述 XML 转换为有意义的数据
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="include-control-elements">true</xsl:param>
<xsl:key name="RECORDS" match="/Poll/SQLConnection/SQLCommand/Data/Row" use="../../@identifier"/>
<xsl:key name="TIMEPUNCH" match="/Poll/SQLConnection/SQLCommand[@identifier='TIMEPUNCH']/Data/Row" use="@j"/>
<xsl:template match="/*">
<xsl:element name="{name()}">
<xsl:copy-of select="@*"/>
<xsl:if test="not($include-control-elements = 'false')">
<xsl:apply-templates select="HEADER"/>
<xsl:copy-of select="Location | Environment[*] | Diagnostics"/>
<xsl:call-template name="LaborGroup"/>
</xsl:if>
</xsl:element>
</xsl:template>
<xsl:template name="LaborGroup">
<xsl:variable name="timepunch" select="key('RECORDS','TIMEPUNCH')"/>
<xsl:if test="$timepunch">
<Labor>
<xsl:if test="$timepunch">
<TM0 type="SHIFT">
<xsl:apply-templates select="$timepunch" mode="TIMEPUNCH"/>
</TM0>
</xsl:if>
</Labor>
</xsl:if>
</xsl:template>
<xsl:template match="Row" mode="TIMEPUNCH">
<TM1>
<xsl:attribute name="e"><xsl:value-of select="format-number(@e,'0000')"/></xsl:attribute>
<xsl:apply-templates select="@j|@tips|@sales|@rh" mode="String"/>
<xsl:variable name="varOvrTimeHr" select="@hrs_ovrday+@hrs_ovrwk+@hrs_holida"/>
<xsl:variable name="varRegHour" select="concat(substring-before(format-number( (@rh ),'0.00'),'.'),':', format-number((@rh * 60)mod 60,'00'))"/>
<xsl:variable name="tempVarIn">
<xsl:if test="count(@e) > 1">
<xsl:value-of select="$e"/>
</xsl:if>
<xsl:value-of select="concat(format-number(substring-before(@cin,':'),'00'),':',substring-after(@cin,':'))"/>
</xsl:variable>
<xsl:variable name="VarIn">
<xsl:choose>
<xsl:when test="substring(substring-after(current()/@cin,':'),3,1)='a'">
<xsl:value-of select="concat(substring-before(@sdt,' '),' ', substring-before($tempVarIn,'a'),':00',' ','AM')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(substring-before(@sdt,' '),' ',substring-before($tempVarIn,'p'),':00',' ','PM')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="tempVarOut">
<xsl:value-of select="concat(format-number(substring-before(@cout,':'),'00'),':',substring-after(@cout,':'))"/>
</xsl:variable>
<xsl:variable name="VarOut">
<xsl:choose>
<xsl:when test="substring(substring-after(current()/@cout,':'),3,1)='a'">
<xsl:value-of select="concat(substring-before(@edt,' '),' ',substring-before($tempVarOut,'a'),':00',' ','AM')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(substring-before(@edt,' '),' ',substring-before($tempVarOut,'p'),':00',' ','PM')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:attribute name="pay"><xsl:value-of select="@total_pay"/></xsl:attribute>
<xsl:attribute name="in"><xsl:value-of select="$VarIn"/></xsl:attribute>
<xsl:attribute name="out"><xsl:value-of select="$VarOut"/></xsl:attribute>
<xsl:attribute name="pay"><xsl:value-of select="@total_pay"/></xsl:attribute>
</TM1>
</xsl:template>
<xsl:template match="Row" mode="TM1">
<xsl:apply-templates select="@e" mode="EMPLOYEE_ID"/>
<xsl:apply-templates select="@j | @r | @rh | @rp | @otr | @ot | @op | @wkh | @pay" mode="Number"/>
</xsl:template>
<xsl:template match="@*" mode="String">
<xsl:param name="name" select="name(.)"/>
<xsl:param name="value" select="normalize-space(.)"/>
<xsl:if test="$value">
<xsl:attribute name="{$name}"><xsl:value-of select="$value"/></xsl:attribute>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
输出是
<Poll>
<Labor>
<TM0 type="SHIFT">
<TM1 e="0007" j="630" tips="23" sales="256" rh="4.1833" in="12-03-2017 11:07:00 AM" out="12-03-2017 01:24:00 PM" pay="113.87"/>
<TM1 e="0007" j="630" tips="0" sales="0" rh="4.1833" in="12-03-2017 06:04:00 AM" out="12-03-2017 10:36:00 AM" pay="113.87"/>
<TM1 e="0071" j="400" tips="47.59" sales="357.61" rh="7.5" in="12-03-2017 12:05:00 PM" out="12-03-2017 03:18:00 PM" pay="78.75"/>
<TM1 e="0071" j="500" tips="47.59" sales="357.61" rh="7.5" in="12-03-2017 04:07:00 PM" out="12-03-2017 08:24:00 PM" pay="78.75"/>
</TM0>
</Labor>
</Poll>
现在我只想通过修改 XSLT 得到这样的输出,但无法得到想要的结果
<Poll>
<Labor>
<TM0 type="SHIFT">
<TM1 e="0007" j="630" tips="23" sales="256" in="12-03-2017 11:07:00 AM" out="12-03-2017 01:24:00 PM"/>
<TM1 e="0007" j="630" tips="0" sales="0" in="12-03-2017 06:04:00 AM" out="12-03-2017 10:36:00 AM" />
<TM1 e="0071" j="500" tips="47.59" sales="357.61" in="12-03-2017 04:07:00 PM" out="12-03-2017 08:24:00 PM"/>
<TM1 e="0071" j="400" tips="0" sales="0" in="12-03-2017 12:05:00 PM" out="12-03-2017 03:18:00 PM" />
</TM0>
</Labor>
</Poll>
所需输出的解释
这背后的逻辑如果“e”和“j”相同,那么第一行携带每个属性,但第二条记录只包含“in”和“out”时间,否则属性显示“0”(零)in记录 像: 第一条记录是完整的,它有 "e","j","tips","sales","in","out" 的所有属性:
<TM1 e="0007" j="630" tips="23" sales="256" in="12-03-2017 11:07:00 AM" out="12-03-2017 01:24:00 PM"/>
但同一 e="0007" 的第二条记录仅具有 "e","j","in","out" 的值,而 "tips" 和 "sales" 的值为 0(零),例如:
<TM1 e="0007" j="630" tips="0" sales="0" in="12-03-2017 06:04:00 AM" out="12-03-2017 10:36:00 AM" />
通过在 XSLT 中进行一些更改,它可以实现,但我的逻辑不起作用,我无法这样做。
请看一下!
谢谢!
【问题讨论】:
-
“跳过相同”指的是什么?
Row元素的属性?如果是这样,为什么所需输出中的第二个TM1元素具有tips或sales属性,看起来它们在输入中具有相同的值,为什么不跳过它们? -
行元素的属性是数据集,如果员工代码和职位代码相同则跳过重复记录,如果员工代码相同而职位代码不同则只跳过重复记录像销售、小费和工资率这样的行,因为它们是相同的,而且进出时间不同,所以它们会记录在案。
标签: xml xslt xml-parsing xslt-1.0 xslt-grouping