Import initial din SVN ROAAUTO/Trunk @HEAD
This commit is contained in:
291
COMUN/utile/nfXml/nfxmlread.PRG
Normal file
291
COMUN/utile/nfXml/nfxmlread.PRG
Normal file
@@ -0,0 +1,291 @@
|
||||
************************************************************************************
|
||||
* nfXMLread ( VFP XML PARSER )
|
||||
* Program created by Marco Plaza , 2013-2016 @vfp2nofox
|
||||
* distributed under VFPX license terms
|
||||
* revision 1.0100 2016/08/08
|
||||
* REVISION 1.0500 2016/08/09
|
||||
**************************************************************************************
|
||||
Parameters cXml,_arraysList,xpathExp,_objectTree
|
||||
|
||||
#INCLUDE NFXML.H
|
||||
#Define CRLF Chr(13)+Chr(10)
|
||||
|
||||
_arraysList = Lower(','+Evl(m._arraysList,'')+',')
|
||||
|
||||
Private All
|
||||
|
||||
stackLevels=Astackinfo(aerrs)
|
||||
|
||||
If m.stackLevels > 1
|
||||
calledFrom = 'called From '+aerrs(m.stackLevels-1,4)+' line '+Transform(aerrs(m.stackLevels-1,5))
|
||||
Else
|
||||
calledFrom = ''
|
||||
Endif
|
||||
|
||||
cError = ''
|
||||
|
||||
Do Case
|
||||
Case Vartype(m.cXml) # 'C'
|
||||
xError('nfXML: Must supply a valid Xml string or file name ')
|
||||
Otherwise
|
||||
oXml = nfXmlRead2( cXml,_arraysList,xpathExp , @_objectTree )
|
||||
Endcase
|
||||
|
||||
Return Iif(Vartype(m.oXml)='O',m.oXml,.Null.)
|
||||
|
||||
*------------------------------------------------
|
||||
Procedure xError( cMessage , Lineno )
|
||||
*------------------------------------------------
|
||||
Lineno = Evl(m.lineno,'?')
|
||||
Error 'nfXML ('+m.calledFrom+'): '+CRLF+Transform(m.lineno)+':'+m.cMessage
|
||||
Return To nfXMLread
|
||||
|
||||
*---------------------------------------------------------------
|
||||
Procedure nfXmlRead2( cXml,_arraysList,xpathExp,_objectTree )
|
||||
*---------------------------------------------------------------
|
||||
|
||||
oMsXml = Createobject('msXml.domdocument')
|
||||
cError = ''
|
||||
|
||||
With oMsXml As msxml.DOMDocument
|
||||
|
||||
.Async = .F.
|
||||
|
||||
If Len(m.cXml) < 200 And File(m.cXml)
|
||||
.Load( m.cXml )
|
||||
Else
|
||||
.LoadXML(m.cXml)
|
||||
Endif
|
||||
|
||||
|
||||
If !Empty(.parseError.reason)
|
||||
|
||||
cError = 'nfXmlRead: '+Transform(.parseError.Line)+') :'+.parseError.reason
|
||||
Lineno = 0
|
||||
|
||||
Else
|
||||
|
||||
|
||||
If Vartype(m.xpathExp) = 'C'
|
||||
|
||||
Try
|
||||
|
||||
oXmlNodes = .selectNodes(m.xpathExp)
|
||||
|
||||
Catch
|
||||
|
||||
cError = ' invalid XPATH expression ('+m.xpathExp+')'
|
||||
Lineno = 0
|
||||
|
||||
Endtry
|
||||
|
||||
|
||||
Else
|
||||
|
||||
oXmlNodes = .childnodes()
|
||||
|
||||
Endif
|
||||
|
||||
If Vartype(m.oXmlNodes) = 'O' And Empty(m.cError)
|
||||
|
||||
Try
|
||||
oVfp = Createobject('empty')
|
||||
recnodo(m.oXmlNodes,m.oVfp,'',_arraysList,@_objectTree)
|
||||
Catch To oErr
|
||||
cError = oErr.Message
|
||||
Lineno = oErr.Lineno
|
||||
Endtry
|
||||
|
||||
Endif
|
||||
|
||||
|
||||
Endif
|
||||
|
||||
Endwith
|
||||
|
||||
If !Empty(m.cError)
|
||||
xError( m.cError , m.lineno )
|
||||
Else
|
||||
Return m.oVfp
|
||||
Endif
|
||||
|
||||
|
||||
*---------------------------------------------------------------------------------
|
||||
Procedure recnodo( oNodos, esteo , _parentNode , _arraysList , _objectTree )
|
||||
*---------------------------------------------------------------------------------
|
||||
|
||||
Private All
|
||||
|
||||
|
||||
For Each nodo In oNodos
|
||||
|
||||
With nodo
|
||||
|
||||
|
||||
If .nodeType # 1 And .nodeType # 3
|
||||
Loop
|
||||
Endif
|
||||
|
||||
|
||||
esTextNode = .nodeType = 3 Or ( .childnodes.Length = 1 And ( .firstchild.nodeType = 3 Or .firstchild.nodeType = 4 ) )
|
||||
emptyNode = .childnodes.Length = 0
|
||||
|
||||
TRY
|
||||
tieneAtributos = .Attributes.Length > 0
|
||||
CATCH
|
||||
tieneAtributos = .F.
|
||||
ENDTRY
|
||||
|
||||
NombreNodo = conv2asc(.nodeName)
|
||||
* Sunt cazuri in care comentariul este in interiorul nodului si numele nodului este #text
|
||||
IF NombreNodo = "#text"
|
||||
Loop
|
||||
ENDIF
|
||||
NombreNodoFix = '_'+m.NombreNodo
|
||||
|
||||
nuevoNodo = Type('esteo.&nombreNodo') = 'U' And Type('esteo.&nombreNodoFix') = 'U'
|
||||
|
||||
Do Case
|
||||
Case m.emptyNode And !m.tieneAtributos
|
||||
nuevoValor = ''
|
||||
Case m.esTextNode And !m.tieneAtributos
|
||||
nuevoValor = .firstchild.nodeValue
|
||||
Otherwise
|
||||
nuevoValor = Createobject('empty')
|
||||
Endcase
|
||||
|
||||
If m.nuevoNodo
|
||||
|
||||
llSelectNodes = .F.
|
||||
TRY
|
||||
llSelectNodes = (.selectNodes('../'+.nodeName).Length > 1)
|
||||
CATCH
|
||||
ENDTRY
|
||||
|
||||
If Lower(','+_parentNode+'.'+.nodeName+'[],') $ m._arraysList Or m.llSelectNodes
|
||||
|
||||
Try
|
||||
AddProperty(m.esteo,(m.NombreNodo+'(1)'))
|
||||
|
||||
Catch
|
||||
|
||||
NombreNodo = m.NombreNodoFix
|
||||
|
||||
AddProperty(m.esteo,(m.NombreNodo+'(1)'))
|
||||
|
||||
Endtry
|
||||
|
||||
esteo.&NombreNodo(1) = m.nuevoValor
|
||||
elemProc = 'esteo.'+m.NombreNodo+'(1)'
|
||||
arrayType = .T.
|
||||
|
||||
Else
|
||||
|
||||
AddProperty(m.esteo,m.NombreNodo,m.nuevoValor)
|
||||
elemProc = 'esteo.'+m.NombreNodo
|
||||
arrayType = .F.
|
||||
|
||||
Endif
|
||||
|
||||
propertyName = m.NombreNodo
|
||||
|
||||
Else
|
||||
|
||||
If Type('esteo.&nombreNodoFix') = 'U'
|
||||
nombreArray = m.NombreNodo
|
||||
Else
|
||||
nombreArray = m.NombreNodoFix
|
||||
Endif
|
||||
|
||||
nvoelem = Alen(esteo.&nombreArray)+1
|
||||
nelemx = Alen(esteo.&nombreArray)
|
||||
|
||||
Dimension esteo.&nombreArray( m.nvoelem )
|
||||
esteo.&nombreArray( nvoelem ) = m.nuevoValor
|
||||
elemProc = 'esteo.'+m.nombreArray+'('+Transform(m.nvoelem)+')'
|
||||
|
||||
propertyName = m.nombreArray
|
||||
arrayType = .T.
|
||||
|
||||
Endif
|
||||
|
||||
If Vartype(m._objectTree) = 'C'
|
||||
|
||||
estaProp = m._parentNode+'.'+m.propertyName+Iif(m.arrayType,'[]','')
|
||||
|
||||
If Not m.estaProp $ m._objectTree
|
||||
_objectTree = m._objectTree+ m.estaProp+Iif( .nodeName # m.propertyName,' <= (.'+.nodeName+')','')+CRLF
|
||||
Endif
|
||||
|
||||
Endif
|
||||
|
||||
|
||||
If m.tieneAtributos
|
||||
|
||||
If m.esTextNode
|
||||
AddProperty(&elemProc,NODETEXTTAG,.firstchild.nodeValue)
|
||||
|
||||
If Vartype(m._objectTree) = 'C'
|
||||
estaProp = m._parentNode+'.'+NODETEXTTAG
|
||||
If Not m.estaProp $ m._objectTree
|
||||
_objectTree = m._objectTree+m.estaProp+CRLF
|
||||
Endif
|
||||
Endif
|
||||
|
||||
|
||||
Endif
|
||||
|
||||
AddProperty(&elemProc,ATTRIBUTETAG,Createobject('empty'))
|
||||
|
||||
oa = m.elemProc+'.'+ATTRIBUTETAG
|
||||
|
||||
For Each atributo In .Attributes
|
||||
|
||||
nombreAtr = conv2asc(atributo.Name)
|
||||
|
||||
Try
|
||||
AddProperty(&oa,m.nombreAtr,atributo.Value)
|
||||
Catch
|
||||
m.nombreAtr = '_'+m.nombreAtr
|
||||
AddProperty(&oa,m.nombreAtr,atributo.Value)
|
||||
Endtry
|
||||
|
||||
If Vartype(m._objectTree) = 'C'
|
||||
estaProp = m._parentNode+'.'+m.propertyName+'.'+ATTRIBUTETAG+'.'+m.nombreAtr
|
||||
If Not m.estaProp $ m._objectTree
|
||||
_objectTree = m._objectTree+m.estaProp+Iif( atributo.Name # m.nombreAtr,' <= (.'+atributo.Name+')','')+CRLF
|
||||
Endif
|
||||
Endif
|
||||
|
||||
Endfor
|
||||
|
||||
Endif
|
||||
|
||||
If !m.esTextNode And .childnodes.Length > 0
|
||||
=recnodo( .childnodes(), &elemProc , _parentNode+'.'+m.propertyName+Iif(m.arrayType,'[]',''), _arraysList , @_objectTree )
|
||||
Endif
|
||||
|
||||
Endwith
|
||||
|
||||
|
||||
Endfor
|
||||
|
||||
|
||||
*------------------------------
|
||||
Function conv2asc( cTag )
|
||||
*------------------------------
|
||||
|
||||
cTag = Strtran(m.cTag,'_','__')
|
||||
|
||||
cTag = Strtran(m.cTag,':','_')
|
||||
cTag = Strtran(m.cTag,'(','_l_')
|
||||
cTag = Strtran(m.cTag,')','_r_')
|
||||
cTag = Strtran(m.cTag,'-','_h_')
|
||||
cTag = Strtran(m.cTag,'.','_d_')
|
||||
|
||||
|
||||
Return cTag
|
||||
|
||||
|
||||
|
||||
*************************************************************************
|
||||
Reference in New Issue
Block a user