Xquery多个重复节点

Xquery multiple repeating nodes

我需要构建 Node InfoExpoRisco 的多个实例,根据我的要求,每个实例都将由一个不同的值“Matricula”表示。

每个 InfoExpoRisco 有 3 个可以重复的节点:

InfoExpoRisco/AgNocs/AgNoc;
InfoExpoRisco/AgNocs/AgNoc/epis/epi;
InfoExpoRisco/responsaveisReg/respReg

declare variable $dbOutput as element()* external;
declare variable $request as element()*external;

declare function local:ObterS2240InfoExpRiscoResponse($dbOutput as element()* (:: schema-element(ns1:ObterS2240InfoExpRisco_dbOutputCollection)* ::), 
                                                      $request as element()* (:: schema-element(ns2:ObterS2240InfoExpRiscoRequest)* ::)) 
                                                      as element()* (:: schema-element(ns2:ObterS2240InfoExpRiscoResponse)* ::) {
    <ns2:ObterS2240InfoExpRiscoResponse>
        {
          for $matriculaRequest in distinct-values($request/ns2:Agente/ns2:Matricula/text())
            for $ObterS2240InfoExpRisco_dbOutput in $dbOutput/ns1:ObterS2240InfoExpRisco_dbOutput
              where $ObterS2240InfoExpRisco_dbOutput/ns1:MATRICULA/text() = $matriculaRequest
            return
            
            <ns2:InfoExpoRisco>
                <ns2:sistemaOrigem>{fn:data($ObterS2240InfoExpRisco_dbOutput/ns1:SISTEMA_ORIGEM)}</ns2:sistemaOrigem>
                <ns2:cdSapEmpresa>{fn:data($ObterS2240InfoExpRisco_dbOutput/ns1:CD_SAP_EMPRESA)}</ns2:cdSapEmpresa>
                <ns2:matricula>{fn:data($ObterS2240InfoExpRisco_dbOutput/ns1:MATRICULA)}</ns2:matricula>
                <ns2:dataAtualizacao>{fn:data($ObterS2240InfoExpRisco_dbOutput/ns1:DATA_ATUALIZACAO)}</ns2:dataAtualizacao>
                <ns2:dtIniCondicao>{fn:data($ObterS2240InfoExpRisco_dbOutput/ns1:DTINICONDICAO)}</ns2:dtIniCondicao>
                <ns2:localAmb>{fn:data($ObterS2240InfoExpRisco_dbOutput/ns1:LOCALAMB)}</ns2:localAmb>
                <ns2:dscSetor>{fn:data($ObterS2240InfoExpRisco_dbOutput/ns1:DSCSETOR)}</ns2:dscSetor>
                <ns2:tpInsc>{fn:data($ObterS2240InfoExpRisco_dbOutput/ns1:TPINSC)}</ns2:tpInsc>
                <ns2:nrInsc>{fn:data($ObterS2240InfoExpRisco_dbOutput/ns1:NRINSC)}</ns2:nrInsc>
                <ns2:dscAtivDes>{fn:data($ObterS2240InfoExpRisco_dbOutput/ns1:DSCATIVDES)}</ns2:dscAtivDes>
                <ns2:obsCompl>{fn:data($ObterS2240InfoExpRisco_dbOutput/ns1:OBSCOMPL)}</ns2:obsCompl>
                
                <ns2:agNocs>
                  {
                    for $agNoc in $dbOutput/ns1:ObterS2240InfoExpRisco_dbOutput
                      where $agNoc/ns1:MATRICULA/text() = $matriculaRequest
                    return
                
                    <ns2:agNoc>
                        {
                          if(fn:data($agNoc/ns1:CODAGNOC ne '')) then(
                          <ns2:codAgNoc>{fn:data($agNoc/ns1:CODAGNOC)}</ns2:codAgNoc>) else()
                        }
                        {
                          if(fn:data($agNoc/ns1:DSCAGNOC ne '')) then(
                          <ns2:dscAgNoc>{fn:data($agNoc/ns1:DSCAGNOC)}</ns2:dscAgNoc>) else()
                        }
                        {
                          if(fn:data($agNoc/ns1:TPAVAL ne '')) then(
                          <ns2:tpAval>{fn:data($agNoc/ns1:TPAVAL)}</ns2:tpAval>) else()
                        }
                        {
                          if(fn:data($agNoc/ns1:INTCONC ne '')) then(
                          <ns2:intConc>{fn:data($agNoc/ns1:INTCONC)}</ns2:intConc>) else()
                        }
                        {
                          if(fn:data($agNoc/ns1:LIMTOL ne '')) then(
                          <ns2:limTol>{fn:data($agNoc/ns1:LIMTOL)}</ns2:limTol>) else()
                        }
                        {
                          if(fn:data($agNoc/ns1:UNMED ne '')) then(
                          <ns2:unMed>{fn:data($agNoc/ns1:UNMED)}</ns2:unMed>) else()
                        }
                        {
                          if(fn:data($agNoc/ns1:TECMEDICAO ne '')) then(
                          <ns2:tecMedicao>{fn:data($agNoc/ns1:TECMEDICAO)}</ns2:tecMedicao>) else()
                        }
                        
                        <ns2:epcEpi>
                            <ns2:utilizEPC>{fn:data($agNoc/ns1:UTILIZEPC)}</ns2:utilizEPC>
                            <ns2:eficEpc>{fn:data($agNoc/ns1:EFICEPC)}</ns2:eficEpc>
                            <ns2:utilizEPI>{fn:data($agNoc/ns1:UTILIZEPI)}</ns2:utilizEPI>
                            <ns2:eficEpi>{fn:data($agNoc/ns1:agno_EFICEPI)}</ns2:eficEpi>
                        </ns2:epcEpi>
                        
                        <ns2:epis>
                          {
                            for $epi in $dbOutput/ns1:ObterS2240InfoExpRisco_dbOutput
                              where $epi/ns1:MATRICULA/text() = $matriculaRequest
                            return 
                
                            <ns2:epi>
                                    
                                {
                                  if(fn:data($epi/ns1:DOCAVAL ne '')) then(
                                  <ns2:docAval>{fn:data($epi/ns1:DOCAVAL)}</ns2:docAval>) else()
                                }
                                {
                                  if(fn:data($epi/ns1:DSCEPI ne '')) then(
                                  <ns2:dscEPI>{fn:data($epi/ns1:DSCEPI)}</ns2:dscEPI>) else()
                                }
                                {
                                  if(fn:data($epi/ns1:MEDPROTECAO ne '')) then(
                                  <ns2:medProtecao>{fn:data($epi/ns1:MEDPROTECAO)}</ns2:medProtecao>) else()
                                }
                                {
                                  if(fn:data($epi/ns1:CONDFUNCTO ne '')) then(
                                  <ns2:condFuncto>{fn:data($epi/ns1:CONDFUNCTO)}</ns2:condFuncto>) else()
                                }
                                {
                                  if(fn:data($epi/ns1:USOININT ne '')) then(
                                  <ns2:usoInint>{fn:data($epi/ns1:USOININT)}</ns2:usoInint>) else()
                                }
                                {
                                  if(fn:data($epi/ns1:PRZVALID ne '')) then(
                                  <ns2:przValid>{fn:data($epi/ns1:PRZVALID)}</ns2:przValid>) else()
                                }
                                {
                                  if(fn:data($epi/ns1:PERIODICTROCA ne '')) then(
                                  <ns2:periodicTroca>{fn:data($epi/ns1:PERIODICTROCA)}</ns2:periodicTroca>) else()
                                }
                                {
                                  if(fn:data($epi/ns1:HIGIENIZACAO ne '')) then(
                                  <ns2:higienizacao>{fn:data($epi/ns1:HIGIENIZACAO)}</ns2:higienizacao>) else()
                                }
                                
                            </ns2:epi>

                            
                          }                
                
                        </ns2:epis>
                
                    </ns2:agNoc>
                    
                  }
                </ns2:agNocs>
                
                <ns2:responsaveisReg>
                  {
                    for $respReg in $dbOutput/ns1:ObterS2240InfoExpRisco_dbOutput
                      where $respReg/ns1:MATRICULA/text() = $matriculaRequest
                    return               
                
                    <ns2:respReg>
                        {
                          if(fn:data($respReg/ns1:CPFRESP ne '')) then(
                          <ns2:cpfResp>{fn:data($respReg/ns1:CPFRESP)}</ns2:cpfResp>) else()
                        }
                        {
                          if(fn:data($respReg/ns1:IDEOC ne '')) then(
                          <ns2:ideOC>{fn:data($respReg/ns1:IDEOC)}</ns2:ideOC>) else()
                        }
                        {
                          if(fn:data($respReg/ns1:DSCOC ne '')) then(
                          <ns2:dscOC>{fn:data($respReg/ns1:DSCOC)}</ns2:dscOC>) else()
                        }
                        {
                          if(fn:data($respReg/ns1:NROC ne '')) then(
                          <ns2:nrOC>{fn:data($respReg/ns1:NROC)}</ns2:nrOC>) else()
                        }
                        {
                          if(fn:data($respReg/ns1:UFOC ne '')) then(
                          <ns2:ufOC>{fn:data($respReg/ns1:UFOC)}</ns2:ufOC>) else()
                        }
                        {
                          if(fn:data($respReg/ns1:MATR_CPF_FUA0017_010 ne '')) then(
                          <ns2:MATR_CPF_FUA0017_010>{fn:data($respReg/ns1:MATR_CPF_FUA0017_010)}</ns2:MATR_CPF_FUA0017_010>) else()
                        }
                        {
                          if(fn:data($respReg/ns1:RESP_TEC_ALA0001_440 ne '')) then(
                          <ns2:RESP_TEC_ALA0001_440>{fn:data($respReg/ns1:RESP_TEC_ALA0001_440)}</ns2:RESP_TEC_ALA0001_440>) else()
                        }
                        
                    </ns2:respReg>
                      
                                        
                  }
                </ns2:responsaveisReg>
                
            </ns2:InfoExpoRisco>
          
        }
    </ns2:ObterS2240InfoExpRiscoResponse>

对于此 $dbOutput

示例,缺少过滤重复节点的内容
<ObterS2240InfoExpRisco_dbOutputCollection xmlns="http://xmlns.oracle.com/pcbpel/adapter/db/ObterS2240InfoExpRisco"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
    <ObterS2240InfoExpRisco_dbOutput>
        <SISTEMA_ORIGEM>2</SISTEMA_ORIGEM>
        <CD_SAP_EMPRESA>1000</CD_SAP_EMPRESA>
        <MATRICULA>5413803</MATRICULA>
        <DATA_ATUALIZACAO>2021-09-01 17:01:17</DATA_ATUALIZACAO>
        <DTINICONDICAO>2021-02-01 00:00:00</DTINICONDICAO>
        <LOCALAMB>1</LOCALAMB>
        <DSCSETOR>RECAP REF DE CAPUAVA</DSCSETOR>
        <TPINSC>1</TPINSC>
        <NRINSC>33000167085263</NRINSC>
        <DSCATIVDES>Analises de amostras, Atividade Administrativa, Drenagem de sistema, Manuseio de Equipamento</DSCATIVDES>
        <OBSCOMPL/>
        <MATR_CPF_FUA0017_010/>
        <RESP_TEC_ALA0001_440/>
        <CPFRESP>23807862080</CPFRESP>
        <IDEOC>4</IDEOC>
        <DSCOC/>
        <NROC>1234</NROC>
        <UFOC>GO</UFOC>
        <CODAGNOC>02.01.001</CODAGNOC>
        <DSCAGNOC>Ruído contínuo ou intermitente (Q5)</DSCAGNOC>
        <TPAVAL>1</TPAVAL>
        <INTCONC>83</INTCONC>
        <LIMTOL/>
        <UNMED>4</UNMED>
        <TECMEDICAO>NR 15 - ANEXO 1 (q=5)</TECMEDICAO>
        <UTILIZEPC>2</UTILIZEPC>
        <EFICEPC>S</EFICEPC>
        <UTILIZEPI>1</UTILIZEPI>
        <agno_EFICEPI/>
        <DOCAVAL/>
        <DSCEPI/>
        <MEDPROTECAO/>
        <CONDFUNCTO/>
        <USOININT/>
        <PRZVALID/>
        <PERIODICTROCA/>
        <HIGIENIZACAO/>
    </ObterS2240InfoExpRisco_dbOutput>
    <ObterS2240InfoExpRisco_dbOutput>
        <SISTEMA_ORIGEM>2</SISTEMA_ORIGEM>
        <CD_SAP_EMPRESA>1000</CD_SAP_EMPRESA>
        <MATRICULA>5413803</MATRICULA>
        <DATA_ATUALIZACAO>2021-09-01 17:01:17</DATA_ATUALIZACAO>
        <DTINICONDICAO>2021-02-01 00:00:00</DTINICONDICAO>
        <LOCALAMB>1</LOCALAMB>
        <DSCSETOR>RECAP REF DE CAPUAVA</DSCSETOR>
        <TPINSC>1</TPINSC>
        <NRINSC>33000167085263</NRINSC>
        <DSCATIVDES>Analises de amostras, Atividade Administrativa, Drenagem de sistema, Manuseio de Equipamento</DSCATIVDES>
        <OBSCOMPL/>
        <MATR_CPF_FUA0017_010/>
        <RESP_TEC_ALA0001_440/>
        <CPFRESP>05611780709</CPFRESP>
        <IDEOC>9</IDEOC>
        <DSCOC>CRQ</DSCOC>
        <NROC>857496</NROC>
        <UFOC>RJ</UFOC>
        <CODAGNOC>02.01.001</CODAGNOC>
        <DSCAGNOC>Ruído contínuo ou intermitente (Q5)</DSCAGNOC>
        <TPAVAL>1</TPAVAL>
        <INTCONC>83</INTCONC>
        <LIMTOL/>
        <UNMED>4</UNMED>
        <TECMEDICAO>NR 15 - ANEXO 1 (q=5)</TECMEDICAO>
        <UTILIZEPC>2</UTILIZEPC>
        <EFICEPC>S</EFICEPC>
        <UTILIZEPI>1</UTILIZEPI>
        <agno_EFICEPI/>
        <DOCAVAL/>
        <DSCEPI/>
        <MEDPROTECAO/>
        <CONDFUNCTO/>
        <USOININT/>
        <PRZVALID/>
        <PERIODICTROCA/>
        <HIGIENIZACAO/>
    </ObterS2240InfoExpRisco_dbOutput>
</ObterS2240InfoExpRisco_dbOutputCollection>

这个例子应该是 1 个 InfoExpoRisco,1 个 AgNoc/0 Epi 和 2 个 RespReg。
我有 4 个 AgNocs 的更糟糕的例子,每个有 4 个 Epis 但最大数字限制不要让我在这里粘贴

解决了使用 functx:distinct-deep 和特定函数列出所有重复节点的问题。然后一个主函数调用所有函数作为不同的深度。