//----------------------------------------------------------------------------/
FUNCTION LoadXml( hFile, cBDPathFull, aTagIter )
Local oXmlDoc, oXmlIter
Local lAbreaqui := .F.
//Local oTagActual, oTagLast, aRoots := {}
Local oTagActual, oTagLast := {}
Local litetagA := ""
Local litetagB := ""
Local nContador := 0
Local aXml := {}
Local cDummy := ""
/* Tag iteratius i sumatori de iteracions trovades.
L'estructura de l'array es:
- 1er. element el tag que pot ser iteratiu
- 2on. element el número de iteració del tag.
*/
/*
Local aTagIter := { {"/Document/CstmrDrctDbtInitn/PmtInf/", 0}, ;
{"/Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf/", 0}, ;
{"/Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf/Dbtr/PstlAdr/AdrLine/", 0} }
*/
//Msgnowait( AMPAarra, GetTrad("Atenció!"), GetTrad("Llegint el fitxer: ") + cBDPathFull )
// Cal ordenar la array per a que es puguin controlar correctament les iteracions.
aTagIter := Asort( aTagIter,,, { |x, y| x[1] < y[1] } )
If hFile = 0
hFile = FOpen( cBDPathFull )
lAbreaqui := .T.
EndIf
oXmlDoc = TXmlDocument():New( hFile )
oXmlIter = TXmlIterator():New( oXmlDoc:oRoot )
oTagActual := oTagLast := Nil
litetagA := "/"
while ( oTagActual := oXmlIter:Next() ) != nil
//Traza( 1, "oTagActual:Depth()-oTagActual:cName=", oTagActual:Depth(), "-", oTagActual:cName )
If oTagLast != nil
if oTagLast:Depth() < oTagActual:Depth()
litetagA := litetagA + oTagActual:cName + "/"
endif
if oTagLast:Depth() > oTagActual:Depth()
//Traza( 1, "litetagA=", litetagA )
litetagB := "/"
For nContador := 1 To ( oTagActual:Depth() - 1 )
litetagB := litetagB + StrToken( litetagA, nContador, "/" ) + "/"
EndFor
litetagA := litetagB
If Empty(oTagActual:cName)
litetagA := litetagA + "/"
Else
litetagA := litetagA + oTagActual:cName + "/"
EndIf
//litetagA := CheckItera( litetagA, aTagIter )
endif
if oTagLast:Depth() == oTagActual:Depth()
//Traza( 1, "litetagA=", litetagA )
litetagB := "/"
For nContador := 1 To ( oTagActual:Depth() - 1 )
litetagB := litetagB + StrToken( litetagA, nContador, "/" ) + "/"
EndFor
litetagA := litetagB
If Empty(oTagActual:cName)
litetagA := litetagA + "/"
Else
litetagA := litetagA + oTagActual:cName + "/"
EndIf
//litetagA := CheckItera( litetagA, aTagIter )
endif
litetagA := CheckItera( litetagA, aTagIter )
else
If .Not. Empty(oTagActual:cName)
litetagA := litetagA + oTagActual:cName + "/"
EndIf
//Traza( 1, "litetagA=", litetagA )
endif
//litetagA := CheckItera( litetagA, aTagIter )
// Aquí es captura el TAG, el seu valor y els atributs si en té.
// exemple: { "/Document/CstmrDrctDbtInitn/PmtInf<1>/DrctDbtTxInf<2>/Dbtr/PstlAdr/AdrLine<1>/", "BARCINO, 29 P-D - SELVA NEGRA", {} }
// { "/Document/CstmrDrctDbtInitn/PmtInf<1>/DrctDbtTxInf<2>/Dbtr/PstlAdr/AdrLine<2>/", "08750 Vallirana", {} }
// Es captura el TAG si té data o si hi han atributs del TAG.
If .Not. Empty( oTagActual:cData ) .or. Len( oTagActual:aAttributes ) > 0
AADD( aXml, { litetagA, oTagActual:cData, {} } )
HEval( oTagActual:aAttributes,;
{ | cKey, cData | AADD( ATail( aXml )[3], { cKey, cData } ) } )
EndIf
/* En aquesta traza s'enregistren els TAG i els seus valors.
------------------------------------------------------ */
/*
cDummy := ""
HEval( oTagActual:aAttributes,;
{ | cKey, cData | cDummy := cDummy + cKey + ":" + cData + "-" } )
If .Not. Empty( oTagActual:cData ) .or. Len( oTagActual:aAttributes ) > 0
Traza( 1, "litetagA=", litetagA, "..", oTagActual:cData, "..", cDummy, "..", Len( ATail( aXml )[3]) )
EndIf
*/
//Traza( 1, "" )
oTagLast = oTagActual
end
If lAbreaqui
FClose( hFile )
EndIf
//EndMsgNoWait( AMPAarra )
// Podem ordenar l'array... però crec que no serà necessari.
//aXml := Asort( aXml,,, { |x, y| x[1] < y[1] } )
//Traza( 1 , aXml )
Return aXml
//----------------------------------------------------------------------------//
FUNCTION CheckItera( litetagA, aTagIter )
/* litetagA es reb acabat en '/'.
Aquesta funció es llença al moment d'afegir un node de XML a litetagA, i
es comprova si aquest nou node afegit és iteratiu, i si és el cas s'el
numera. A la resta de nodes que arriberien a 'penjar' d'ell s'els posa
el numeral a '0', doncs es tractaria d'una nova captura de nodes iteratius.
Per a que la possada a zero de les iteracions que penjen de la que
estem examinant, cal que aTagIter estigui ordenada ascendentment.
------------------------------------------------------------------------ */
Local cCadena := litetagA
Local nContadorA := 0
Local nContadorB := 0
Local PosA := 0
Local PosB := 0
Local LenaTagIter := 0
Local LencCadena := 0
Do While (PosA := AT( "<", cCadena) ) > 0
//Traza( 1 , "a-cCadena=", cCadena )
PosB := AT( ">", cCadena )
cCadena := Left( cCadena, PosA - 1 ) + SubStr( cCadena, PosB + 1 )
//Traza( 1 , "b-cCadena=", cCadena )
End
If ( nContadorA := ASCan( aTagIter, { |aVal| aVal[1] = cCadena } ) ) > 0
/* Poso la resta d'elements iteratius que penjen del que estem examinant a zero (0).
------------------------------------------------------------------------------ */
LenaTagIter := Len(aTagIter)
LencCadena := Len(cCadena)
For nContadorB := ( nContadorA + 1 ) To LenaTagIter
If cCadena = Left( aTagIter[nContadorB][1], LencCadena )
aTagIter[nContadorB][2] := 0
EndIf
EndFor
aTagIter[ nContadorA ][2] ++
cCadena := Left( litetagA, Len(litetagA) - 1 ) + "<" + AllTrim(Str(aTagIter[ nContadorA ][2], 10,0)) + ">/"
Else
cCadena := litetagA
EndIf
Return cCadena
//----------------------------------------------------------------------------//