当我尝试通过应用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>
期望输出的解释
这背后的逻辑如果&#34; e&#34;和&#34; j&#34;是相同的,然后顶行携带每个属性,但第二个记录只包含&#34; in&#34;和&#34; out&#34;其他属性在记录中显示&#34; 0&#34;(零) 喜欢: 第一条记录已经完成,它有&#34; e&#34;&#34; j&#34;,&#34;提示&#34;,&#34;销售&#34;,&#34;&#34;&#34; ;,&#34;列&#34;所有属性:
<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 =&#34;&#34;只有&#34; e&#34;,&#34; j&#34;,&#34;&#34;,&#34; out&#34; &#34;提示&#34; 0和0(零)和&#34;销售&#34;喜欢:
<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中进行一些更改,它可以实现,但我的逻辑不起作用,我不能这样做。
请看一下!
谢谢!
答案 0 :(得分:0)
您共享的XSLT包含对示例XML中未包含的元素的一些额外处理,因此不是修改共享XSLT,下面的解决方案中包含了一个新的XSLT,以便了解所需的内容分组可以实现。
您可以使用@e
元素的@j
和<Row>
属性创建复合键。
<xsl:key name="ej-key" match="Row" use="concat(@e,'|', @j)" />
使用此密钥并将<Row>
与generate-id()
功能相匹配,可以实现所需的分组。
<xsl:template match="Row[generate-id() = generate-id(key('ej-key', concat(@e,'|',@j))[1])]">
以下是XSLT。 XSLT不包含计算@in
和@out
属性 值的逻辑。您可以在模板中添加该逻辑。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:key name="ej-key" match="Row" use="concat(@e,'|', @j)" />
<xsl:template match="Poll">
<xsl:copy>
<Labor>
<xsl:apply-templates />
</Labor>
</xsl:copy>
</xsl:template>
<xsl:template match="Data">
<xsl:element name="TM0">
<xsl:attribute name="type">
<xsl:value-of select="'SHIFT'" />
</xsl:attribute>
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="Row[generate-id() = generate-id(key('ej-key', concat(@e,'|',@j))[1])]">
<xsl:variable name="varKey" select="key('ej-key', concat(@e,'|', @j))" />
<xsl:element name="TM1">
<xsl:attribute name="e">
<xsl:value-of select="format-number($varKey/@e, '0000')" />
</xsl:attribute>
<xsl:attribute name="j">
<xsl:value-of select="$varKey/@j" />
</xsl:attribute>
<xsl:attribute name="tips">
<xsl:value-of select="$varKey/@tips" />
</xsl:attribute>
<xsl:attribute name="sales">
<xsl:value-of select="$varKey/@sales" />
</xsl:attribute>
<xsl:attribute name="rh">
<xsl:value-of select="$varKey/@rh" />
</xsl:attribute>
</xsl:element>
</xsl:template>
<xsl:template match="Row" />
</xsl:stylesheet>
输出
<Poll>
<Labor>
<TM0 type="SHIFT">
<TM1 e="0007" j="630" tips="0" sales="0" rh="4.1833" />
<TM1 e="0071" j="400" tips="47.59" sales="357.61" rh="7.5" />
<TM1 e="0071" j="500" tips="47.59" sales="357.61" rh="7.5" />
</TM0>
</Labor>
</Poll>