如何使用XSLT根据条件获取两个相同级别的节点值?

时间:2019-05-02 18:10:09

标签: xslt xslt-2.0

我是XSLT代码的新手,需要您的帮助。我正在使用XML构建报告,并且需要基于两个节点之间的条件来转换必填字段的XML。我几乎完成了逻辑,但是对于其中一条记录,由于多个相同的节点,我的逻辑无法正常工作。

从下面的xml输出中:我需要将Worker_Events_Complete_Group-> EffectiveDate与Job_History_group有效日期进行匹配,并仅在匹配时才显示字段。

<Report_Entry>
<Employee_ID>50067</Employee_ID>
<Worker>John Grisolano</Worker>
<Worker_Events_Completed_group>
    <EffectiveDate>2019-01-01</EffectiveDate>
    <DateTimeCompleted>2019-01-09T14:23:06.679-08:00</DateTimeCompleted>
    <Business_Process_Type>Transfer Employee</Business_Process_Type>
</Worker_Events_Completed_group>
<Worker_Events_Completed_group>
    <EffectiveDate>2019-04-01</EffectiveDate>
    <DateTimeCompleted>2019-04-03T07:53:43.965-07:00</DateTimeCompleted>
    <Business_Process_Type>Transfer Employee</Business_Process_Type>
</Worker_Events_Completed_group>
<Job_History_group>
    <Effective_Date>2019-01-01</Effective_Date>
    <Class_of_Instance>Position Snapshot</Class_of_Instance>
    <Scheduled_Weekly_Hours>40</Scheduled_Weekly_Hours>
    <Default_Weekly_Hours>40</Default_Weekly_Hours>
</Job_History_group>
<Job_History_group>
    <Effective_Date>2019-04-01</Effective_Date>
    <Class_of_Instance>Position Snapshot</Class_of_Instance>
    <Scheduled_Weekly_Hours>40</Scheduled_Weekly_Hours>
    <Default_Weekly_Hours>40</Default_Weekly_Hours>
</Job_History_group>
</Report_Entry>

我使用的XSLT代码如下:但是由于相同级别的节点而失败,它无法进入Job_History_Group。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:template match="/">
    <ChangeEvent>
        <EmpID><xsl:value-of select="Report_Entry/Employee_ID"/></EmpID>
        <xsl:variable name="Current_Date" select="Report_Entry/Worker_Events_Completed_group/EffectiveDate"/>
        <EventDetails>
            <xsl:for-each select="Report_Entry/Worker_Events_Completed_group">
                <Event>
                    <ChangeEventDate><xsl:value-of select="EffectiveDate"/></ChangeEventDate>
                    <ChangeEntryDate><xsl:value-of select="DateTimeCompleted"/></ChangeEntryDate>
                    <ChangeType><xsl:value-of select="CF_Census_Change_Type"/></ChangeType> 
                    <FTE_Snapshot>
                        <xsl:for-each select="Job_History_group">
                            <Snapshot>
                                <xsl:choose> 
                                    <xsl:when test="$Current_Date = Effective_Date">
                                        <xsl:variable name="swh" select="Scheduled_Weekly_Hours"/>
                                        <xsl:variable name="dwh" select="Default_Weekly_Hours"/>
                                        <Snapshot_EffectiveDate><xsl:value-of select="Effective_Date"/></Snapshot_EffectiveDate>
                                        <Snapshot_FTE><xsl:value-of select="$swh div $dwh * 100"/></Snapshot_FTE>
                                    </xsl:when>
                                    <xsl:otherwise/>
                                </xsl:choose>
                            </Snapshot>
                        </xsl:for-each>
                    </FTE_Snapshot>
                </Event>

            </xsl:for-each> 
        </EventDetails>
    </ChangeEvent>
   </xsl:template>
</xsl:stylesheet>

预期输出如下:

<?xml version="1.0" encoding="UTF-8"?>
<ChangeEvent >
<EmpID>50067</EmpID>
<EventDetails>
    <Event>
        <ChangeEventDate>2019-01-01</ChangeEventDate>
        <ChangeEntryDate>2019-01-09T14:23:06.679-08:00</ChangeEntryDate>
        <ChangeType>Cost Center</ChangeType>
        <FTE_Snapshot>
            <Snapshot>   
                <Effective_Date>2019-01-01</Effective_Date>
                <Class_of_Instance>Position Snapshot</Class_of_Instance>
                <Scheduled_Weekly_Hours>40</Scheduled_Weekly_Hours>
                <Default_Weekly_Hours>40</Default_Weekly_Hours>
            </Snapshot>
        </FTE_Snapshot>
    </Event>
    <Event>
        <ChangeEventDate>2019-04-01</ChangeEventDate>
        <ChangeEntryDate>2019-04-03T07:53:43.965-07:00</ChangeEntryDate>
        <ChangeType>Cost Center</ChangeType>
        <FTE_Snapshot>
          <Snapshot>
            <Effective_Date>2019-04-01</Effective_Date>
            <Class_of_Instance>Position Snapshot</Class_of_Instance>
            <Scheduled_Weekly_Hours>40</Scheduled_Weekly_Hours>
            <Default_Weekly_Hours>40</Default_Weekly_Hours>
          <Snapshot>
        </FTE_Snapshot>
       </Event>
    </EventDetails>
</ChangeEvent>

2 个答案:

答案 0 :(得分:1)

如果我的理解正确,那么您正在Job_History_group的上下文中尝试从Worker_Events_Completed_group查找数据。最好使用 key 完成。

请考虑以下简化示例:

XML

<Report_Entry>
    <Employee_ID>50067</Employee_ID>
    <Worker>John Grisolano</Worker>
    <Worker_Events_Completed_group>
        <EffectiveDate>2019-01-01</EffectiveDate>
        <Local>abc</Local>
    </Worker_Events_Completed_group>
    <Worker_Events_Completed_group>
        <EffectiveDate>2019-04-01</EffectiveDate>
        <Local>def</Local>
    </Worker_Events_Completed_group>
    <Job_History_group>
        <Effective_Date>2019-01-01</Effective_Date>
        <Remote>January</Remote>
    </Job_History_group>
    <Job_History_group>
        <Effective_Date>2019-04-01</Effective_Date>
        <Remote>April</Remote>
    </Job_History_group>
</Report_Entry>

XSLT 1.0

<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:strip-space elements="*"/>

<xsl:key name="job-history" match="Job_History_group" use="Effective_Date" />

<xsl:template match="/Report_Entry">
    <ChangeEvent>
        <EmpID>
            <xsl:value-of select="Employee_ID"/>
        </EmpID>
        <EventDetails>
            <xsl:for-each select="Worker_Events_Completed_group">
                <Event>
                    <ChangeEventDate>
                        <xsl:value-of select="EffectiveDate"/>
                    </ChangeEventDate>
                    <local>
                        <xsl:value-of select="Local"/>
                    </local>
                   <remote>
                        <xsl:value-of select="key('job-history', EffectiveDate)/Remote"/>
                    </remote>
                </Event>
            </xsl:for-each> 
        </EventDetails>
    </ChangeEvent>
</xsl:template>

</xsl:stylesheet>

结果

<?xml version="1.0" encoding="UTF-8"?>
<ChangeEvent>
  <EmpID>50067</EmpID>
  <EventDetails>
    <Event>
      <ChangeEventDate>2019-01-01</ChangeEventDate>
      <local>abc</local>
      <remote>January</remote>
    </Event>
    <Event>
      <ChangeEventDate>2019-04-01</ChangeEventDate>
      <local>def</local>
      <remote>April</remote>
    </Event>
  </EventDetails>
</ChangeEvent>

答案 1 :(得分:0)

我认为您快到了!我将Current_Date移到每个Worker_Events_Completed_group内,添加了../以选择同级节点,然后根据您在条件中提示的匹配条件过滤了Job_History_group:< / p>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output indent="yes" />
    <xsl:template match="/">
        <ChangeEvent>
            <EmpID><xsl:value-of select="Report_Entry/Employee_ID"/></EmpID>           
            <EventDetails>
              <xsl:for-each select="Report_Entry/Worker_Events_Completed_group">
                  <xsl:variable name="Current_Date" select="EffectiveDate"/>
                  <Event>
                      <ChangeEventDate><xsl:value-of select="EffectiveDate"/></ChangeEventDate>
                      <ChangeEntryDate><xsl:value-of select="DateTimeCompleted"/></ChangeEntryDate>
                      <ChangeType><xsl:value-of select="CF_Census_Change_Type"/></ChangeType> 
                      <FTE_Snapshot>  
                          <xsl:for-each select="../Job_History_group[Effective_Date=$Current_Date]">
                              <Snapshot>
                                  <xsl:variable name="swh" select="Scheduled_Weekly_Hours"/>
                                  <xsl:variable name="dwh" select="Default_Weekly_Hours"/>
                                  <Snapshot_EffectiveDate><xsl:value-of select="Effective_Date"/></Snapshot_EffectiveDate>
                                  <Snapshot_FTE><xsl:value-of select="$swh div $dwh * 100"/></Snapshot_FTE>
                              </Snapshot>
                          </xsl:for-each>
                      </FTE_Snapshot>
                  </Event>
                  </xsl:for-each>                   
            </EventDetails>
        </ChangeEvent>
    </xsl:template>
</xsl:stylesheet>