XSLT:如何从上一个位置访问元素

问题描述 投票:0回答:1

我有以下输入 xml 文件:

<?xml version='1.0' encoding='UTF-8'?>
<root>
    <row>
        <userId>40668825871</userId>
        <Cargo>ANL CONTR QUALIDADE SR</Cargo>
        <Atuacao>Interno</Atuacao>
        <Nivel>PROF</Nivel>
        <TipoCargo></TipoCargo>
        <Contrato>CLT</Contrato>
        <Empresa>BRAINFARMA IND. QUIMICA E FARMACEUTICA S.A.</Empresa>
        <GrupoLotacao>BRAINFARMA - ANAPOLIS</GrupoLotacao>
        <Divisao>FARMA</Divisao>
        <Unidade>P&amp;D E QUALIDADE</Unidade>
        <DataInicio>01/01/2023</DataInicio>
        <DataFim>01/08/2023</DataFim>
        <MotivoEvento>Alteração de Reporte</MotivoEvento>
        <Programa>180</Programa>
    </row>
    <row>
        <userId>40668825871</userId>
        <Cargo>ANL CONTR QUALIDADE SR</Cargo>
        <Atuacao>Interno</Atuacao>
        <Nivel>PROF</Nivel>
        <TipoCargo></TipoCargo>
        <Contrato>CLT</Contrato>
        <Empresa>BRAINFARMA IND. QUIMICA E FARMACEUTICA S.A.</Empresa>
        <GrupoLotacao>BRAINFARMA - ANAPOLIS</GrupoLotacao>
        <Divisao>FARMA</Divisao>
        <Unidade>P&amp;D E QUALIDADE</Unidade>
        <DataInicio>01/09/2023</DataInicio>
        <DataFim>01/31/2023</DataFim>
        <MotivoEvento>Alteração de Horário</MotivoEvento>
        <Programa>180</Programa>
    </row>
    <row>
        <userId>40668825871</userId>
        <Cargo>ANL CONTR QUALIDADE SR</Cargo>
        <Atuacao>Interno</Atuacao>
        <Nivel>PROF</Nivel>
        <TipoCargo></TipoCargo>
        <Contrato>CLT</Contrato>
        <Empresa>BRAINFARMA IND. QUIMICA E FARMACEUTICA S.A.</Empresa>
        <GrupoLotacao>BRAINFARMA - ANAPOLIS</GrupoLotacao>
        <Divisao>FARMA</Divisao>
        <Unidade>P&amp;D E QUALIDADE</Unidade>
        <DataInicio>02/01/2023</DataInicio>
        <DataFim>02/28/2023</DataFim>
        <MotivoEvento>Transferência de CDC</MotivoEvento>
        <Programa>180</Programa>
    </row>
    <row>
        <userId>40668825871</userId>
        <Cargo>ANL VALIDACAO SR</Cargo>
        <Atuacao>Interno</Atuacao>
        <Nivel>PROF</Nivel>
        <TipoCargo></TipoCargo>
        <Contrato>CLT</Contrato>
        <Empresa>BRAINFARMA IND. QUIMICA E FARMACEUTICA S.A.</Empresa>
        <GrupoLotacao>BRAINFARMA - ANAPOLIS</GrupoLotacao>
        <Divisao>FARMA</Divisao>
        <Unidade>P&amp;D E QUALIDADE</Unidade>
        <DataInicio>03/01/2023</DataInicio>
        <DataFim>05/05/2023</DataFim>
        <MotivoEvento>Transferência de Estrutura</MotivoEvento>
        <Programa>180</Programa>
    </row>
    <row>
        <userId>40668825871</userId>
        <Cargo>ANL VALIDACAO SR</Cargo>
        <Atuacao>Interno</Atuacao>
        <Nivel>PROF</Nivel>
        <TipoCargo></TipoCargo>
        <Contrato>CLT</Contrato>
        <Empresa>BRAINFARMA IND. QUIMICA E FARMACEUTICA S.A.</Empresa>
        <GrupoLotacao>BRAINFARMA - ANAPOLIS</GrupoLotacao>
        <Divisao>FARMA</Divisao>
        <Unidade>P&amp;D E QUALIDADE</Unidade>
        <DataInicio>05/06/2023</DataInicio>
        <DataFim>12/31/2023</DataFim>
        <MotivoEvento>Alteração de Dados</MotivoEvento>
        <Programa>180</Programa>
    </row>
    <row>
        <userId>34916921801</userId>
        <Cargo>COORD DESENV FARMACOTECNICO</Cargo>
        <Atuacao>Interno</Atuacao>
        <Nivel>COORD</Nivel>
        <TipoCargo></TipoCargo>
        <Contrato>CLT</Contrato>
        <Empresa>BRAINFARMA IND. QUIMICA E FARMACEUTICA S.A.</Empresa>
        <GrupoLotacao>BRAINFARMA - BARUERI</GrupoLotacao>
        <Divisao>FARMA</Divisao>
        <Unidade>P&amp;D E QUALIDADE</Unidade>
        <DataInicio>08/01/2022</DataInicio>
        <DataFim>01/31/2023</DataFim>
        <MotivoEvento>Transferência de Estrutura</MotivoEvento>
        <Programa>180</Programa>
    </row>
    <row>
        <userId>34916921801</userId>
        <Cargo>COORD DESENV EMBALAGENS</Cargo>
        <Atuacao>Interno</Atuacao>
        <Nivel>COORD</Nivel>
        <TipoCargo></TipoCargo>
        <Contrato>CLT</Contrato>
        <Empresa>BRAINFARMA IND. QUIMICA E FARMACEUTICA S.A.</Empresa>
        <GrupoLotacao>BRAINFARMA - BARUERI</GrupoLotacao>
        <Divisao>FARMA</Divisao>
        <Unidade>P&amp;D E QUALIDADE</Unidade>
        <DataInicio>02/01/2023</DataInicio>
        <DataFim>02/28/2023</DataFim>
        <MotivoEvento>1-Enquadramento de cargo</MotivoEvento>
        <Programa>180</Programa>
    </row>
    <row>
        <userId>34916921801</userId>
        <Cargo>COORD DESENV EMBALAGENS</Cargo>
        <Atuacao>Interno</Atuacao>
        <Nivel>COORD</Nivel>
        <TipoCargo></TipoCargo>
        <Contrato>CLT</Contrato>
        <Empresa>BRAINFARMA IND. QUIMICA E FARMACEUTICA S.A.</Empresa>
        <GrupoLotacao>BRAINFARMA - BARUERI</GrupoLotacao>
        <Divisao>FARMA</Divisao>
        <Unidade>P&amp;D E QUALIDADE</Unidade>
        <DataInicio>03/01/2023</DataInicio>
        <DataFim>05/05/2023</DataFim>
        <MotivoEvento>Transferência de Estrutura</MotivoEvento>
        <Programa>180</Programa>
    </row>
    <row>
        <userId>34916921801</userId>
        <Cargo>COORD DESENV EMBALAGENS</Cargo>
        <Atuacao>Interno</Atuacao>
        <Nivel>COORD</Nivel>
        <TipoCargo></TipoCargo>
        <Contrato>CLT</Contrato>
        <Empresa>BRAINFARMA IND. QUIMICA E FARMACEUTICA S.A.</Empresa>
        <GrupoLotacao>BRAINFARMA - BARUERI</GrupoLotacao>
        <Divisao>FARMA</Divisao>
        <Unidade>P&amp;D E QUALIDADE</Unidade>
        <DataInicio>05/06/2023</DataInicio>
        <DataFim>12/31/2023</DataFim>
        <MotivoEvento>Alteração de Dados</MotivoEvento>
        <Programa>180</Programa>
    </row>
    <row>
        <userId>45787737873</userId>
        <Cargo>PROPAGANDISTA JR</Cargo>
        <Atuacao>Campo</Atuacao>
        <Nivel>PROF</Nivel>
        <TipoCargo></TipoCargo>
        <Contrato>CLT</Contrato>
        <Empresa>HYPERA S.A</Empresa>
        <GrupoLotacao>HYPERA - CD GOIANIA</GrupoLotacao>
        <Divisao>FARMA</Divisao>
        <Unidade>VENDAS E MARKETING</Unidade>
        <DataInicio>01/01/2023</DataInicio>
        <DataFim>06/30/2023</DataFim>
        <MotivoEvento>Alteração de Reporte</MotivoEvento>
        <Programa>180</Programa>
    </row>
    <row>
        <userId>45787737873</userId>
        <Cargo>PROPAGANDISTA JR</Cargo>
        <Atuacao>Campo</Atuacao>
        <Nivel>PROF</Nivel>
        <TipoCargo></TipoCargo>
        <Contrato>CLT</Contrato>
        <Empresa>HYPERA S.A</Empresa>
        <GrupoLotacao>HYPERA - CD GOIANIA</GrupoLotacao>
        <Divisao>FARMA</Divisao>
        <Unidade>VENDAS E MARKETING</Unidade>
        <DataInicio>07/01/2023</DataInicio>
        <DataFim>07/31/2023</DataFim>
        <MotivoEvento>Alteração de Dados</MotivoEvento>
        <Programa>180</Programa>
    </row>
    <row>
        <userId>45787737873</userId>
        <Cargo>PROPAGANDISTA JR</Cargo>
        <Atuacao>Campo</Atuacao>
        <Nivel>PROF</Nivel>
        <TipoCargo>OPERACIONAL</TipoCargo>
        <Contrato>CLT</Contrato>
        <Empresa>HYPERA S.A</Empresa>
        <GrupoLotacao>HYPERA - CD GOIANIA</GrupoLotacao>
        <Divisao>FARMA</Divisao>
        <Unidade>VENDAS E MARKETING</Unidade>
        <DataInicio>08/01/2023</DataInicio>
        <DataFim>12/31/2023</DataFim>
        <MotivoEvento>Alteração de Dados</MotivoEvento>
        <Programa>180</Programa>
    </row>
</root>

这基本上是员工在当年工作的时间段,其中每一行代表特定工作的时间段(员工可以有一个或多个工作/行)。

我可以使用以下 XSLT 按员工进行分组,但现在我需要比较当前行和上一行(DataInicio 和 DataFim)之间的日期以生成输出 xml。

我怎样才能做到这一点?我尝试了很多方法,但没有人奏效。

这里是 XSLT(我尝试创建变量 datainicio_ant 来存储上一行中的 DataInicio 字段,但它不起作用)。请有人帮助我吗?

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:hci="http://sap.com/it/" exclude-result-prefixes="hci"
    xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="/">

        <Colaboradores>

            <xsl:for-each-group select="root/row/userId" group-by="text()">

                <Colaborador>
                    <externalCode>
                        <xsl:value-of select="../userId"/>
                    </externalCode>
                    
                    <!-- A data efetiva deve ser o último dia do ano de apuração -->
                    <effectiveStartDate>12/31/<xsl:value-of select="substring(..[1]/DataFim, 7, 4)"/></effectiveStartDate>

                    <xsl:for-each select="current-group()">

                        <xsl:sort select="../DataFim"/>
                        
            <!-- HERE IT'S THE ERROR, HOW CAN I CREATE A VARIABLE WITH THE VALUE OF DataInicio FROM PREVIOUS RECORD?            
            <xsl:variable name="datainicio_ant" select="preceding-sibling::..[1]/DataInicio"/>  -->

                        <xsl:choose>
                            <xsl:when test="position() = 1">
                                <cust_cargo1>
                                    <xsl:value-of select="../Cargo"/>
                                </cust_cargo1>
                                <cust_Data_inic_cargo1>
                                    <xsl:value-of select="../DataInicio"/>
                                </cust_Data_inic_cargo1>
                                <cust_Data_fim_cargo1>
                                    <xsl:value-of select="../DataFim"/>
                                </cust_Data_fim_cargo1>
                           
                            </xsl:when>

                            <xsl:when test="position() = 2">
                               <cust_cargo2>
                                    <xsl:value-of select="../Cargo"/>
                                </cust_cargo2>
                                <cust_Data_inic_cargo2>
                                    <xsl:value-of select="../DataInicio"/>
                                </cust_Data_inic_cargo2>
                                <cust_Data_fim_cargo2>
                                    <xsl:value-of select="../DataFim"/>
                                </cust_Data_fim_cargo2>

                            </xsl:when>

                        </xsl:choose>

                    </xsl:for-each>

                </Colaborador>

            </xsl:for-each-group>

        </Colaboradores>

    </xsl:template>

</xsl:stylesheet>

我只需要修复代码的和平性,其余部分工作正常:

        \<!-- HERE IT'S THE ERROR, HOW CAN I CREATE A VARIABLE WITH THE VALUE OF DataInicio FROM PREVIOUS RECORD?           
        \<xsl:variable name="datainicio_ant" select="preceding-sibling::..\[1\]/DataInicio"/\> -->

编辑2:我尝试应用马丁的建议,但它还没有起作用:

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:hci="http://sap.com/it/" exclude-result-prefixes="hci"
xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
    <Colaboradores>
       <xsl:for-each-group select="root/row/userId" group-by="text()">
            <Colaborador>
                <externalCode>
                    <xsl:value-of select="../userId"/>
                </externalCode>

                <!-- A data efetiva deve ser o último dia do ano de apuração -->
                <effectiveStartDate>12/31/<xsl:value-of select="substring(..[1]/DataFim, 7, 4)"/></effectiveStartDate>
                <xsl:for-each select="current-group()">                 
                <xsl:sort select="../DataFim"/> 

                <!--  BEGIN -->
                <xsl:variable name="pos" select="position()"/>             
                <xsl:variable name="group" select="current-group()"/>                   
                <xsl:variable name="datainicio_ant" select="$group[$pos - 1]/DataInicio"/>                    
                <!--  END -->

                    <xsl:choose>
                        <xsl:when test="position() = 1">
                            <cust_cargo1>
                                <xsl:value-of select="../Cargo"/>
                            </cust_cargo1>
                            <cust_Data_inic_cargo1>
                                <xsl:value-of select="../DataInicio"/>
                            </cust_Data_inic_cargo1>
                            <cust_Data_fim_cargo1>
                                <xsl:value-of select="../DataFim"/>
                            </cust_Data_fim_cargo1>

                        </xsl:when>

                        <xsl:when test="position() = 2">
                           <cust_cargo2>
                                <xsl:value-of select="../Cargo"/>
                            </cust_cargo2>
                            <cust_Data_inic_cargo2>
                                <xsl:value-of select="../DataInicio"/>
                            </cust_Data_inic_cargo2>
                            <cust_Data_fim_cargo2>
                                <xsl:value-of select="../DataFim"/>
                            </cust_Data_fim_cargo2>
                            <!--    BEGIN -->
                            <teste>
                            <xsl:value-of select="$datainicio_ant"/>
                            </teste>
                            <!--    END -->
                        </xsl:when>
                    </xsl:choose>
                </xsl:for-each>
            </Colaborador>
        </xsl:for-each-group>
    </Colaboradores>
</xsl:template>

xml xslt xslt-2.0
1个回答
0
投票

看看这个最小示例是否能让您走上正轨:

XML

<root>
    <row>
        <userId>1</userId>
        <value>1a</value>
    </row>
    <row>
        <userId>2</userId>
        <value>2a</value>
    </row>
    <row>
        <userId>1</userId>
        <value>1b</value>
    </row>
    <row>
        <userId>2</userId>
        <value>2b</value>
    </row>
    <row>
        <userId>1</userId>
        <value>1c</value>
    </row>
</root>

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/root">
    <output>
        <xsl:for-each-group select="row" group-by="userId">
            <group userId="{current-grouping-key()}">
                <xsl:for-each select="current-group()">
                    <xsl:variable name="i" select="position()" />
                    <item>
                        <xsl:copy-of select="value"/>
                        <prev-value>
                            <xsl:value-of select="current-group()[$i - 1]/value"/>
                        </prev-value>
                    </item>
                </xsl:for-each>
            </group>
        </xsl:for-each-group>
    </output>
</xsl:template>

</xsl:stylesheet>

结果

<?xml version="1.0" encoding="UTF-8"?>
<output>
   <group userId="1">
      <item>
         <value>1a</value>
         <prev-value/>
      </item>
      <item>
         <value>1b</value>
         <prev-value>1a</prev-value>
      </item>
      <item>
         <value>1c</value>
         <prev-value>1b</prev-value>
      </item>
   </group>
   <group userId="2">
      <item>
         <value>2a</value>
         <prev-value/>
      </item>
      <item>
         <value>2b</value>
         <prev-value>2a</prev-value>
      </item>
   </group>
</output>
© www.soinside.com 2019 - 2024. All rights reserved.