This function parses some XML-like data.
Still needs some error checking, changes to make it XML compliant, etc...
Feel free to improve this code and share it with the fantastic PureBasic community.
Code: Select all
; Based on Poor Man XML parser! by Marco Pontello 2003
;
; (c) LuckyLuke,07/07/2005
;
Structure _Tag
vName.s ;Tag name
vLevel.l ;Tag level
vValue.s ;Tag value
pParentTag.l ;Pointer to parent tag
pAttr.l ;Pointer to first attribute
EndStructure
Structure _Attribute
pTag.l ;Pointer to tag (index of linkedlist tag)
vName.s ;Attribute name
vValue.s ;Attribute value
EndStructure
Global NewList lTag._Tag()
Global NewList lAttr._Attribute()
Procedure ParseXml(aXml.s)
vTmp.s
vChar.s
vTmpAttr.s
vPos.l=1 ;Global position in aXml
vLevel.l=0
vOldLevel.l
vPrevLevel.l=0
vParentTag.l=0
vPrevParentTag.l=0
While 1=1
vTmp="" ;Reset tmp
i = FindString(aXml,"<", vPos)
j = FindString(aXml,">", vPos)
If i>=j Or i=0
i = j
EndIf
If i=0
Break
EndIf
vChar = Mid(aXml,i,1) ;First char (> or <) from selection
vTmp = Mid(aXml, vPos, i - vPos)
vPos = i + 1
vTmp = Trim(vTmp)
If vTmp<>""
If vChar=">" ;End of tag
If Left(vTmp,1)<>"?" And Right(vTmp,1)<>"?"
If Left(vTmp,1)<>"!" And Right(vTmp,1)<>"/"
vOldLevel = vLevel
If Left(vTmp,1)="/" ;End Tag
vLevel = vLevel - 1
Else
AddElement(lTag())
If CountString(vTmp," ") > 0
lTag()\pAttr = ListSize(lAttr()) + 1
Else
lTag()\pAttr = 0
EndIf
;Attributes
For k=2 To CountString(vTmp," ") + 1
vTmpAttr = StringField(vTmp, k, " ")
AddElement(lAttr())
lAttr()\pTag = ListSize(lTag())
lAttr()\vName = StringField(vTmpAttr,1,"=")
lAttr()\vValue = StringField(vTmpAttr,2,"=")
Next
vTmp = StringField(vTmp, 1, " ")
vLevel = vLevel + 1
lTag()\vName = vTmp
lTag()\vLevel=vLevel
lTag()\pParentTag=vParentTag
EndIf
If vOldLevel<=vLevel
If vLevel > vPrevLevel
vParentTag = vPrevParentTag
vPrevLevel = vLevel
vPrevParentTag = ListSize(lTag())
EndIf
EndIf
lTag()\pParentTag=vParentTag
EndIf
EndIf
Else
lTag()\vValue = vTmp
EndIf
EndIf
Wend
EndProcedure
;Example
xml.s = "<XML><DATA id=1 name=test><NAME>PureBasic</NAME><VERSION>00.00.01</VERSION></DATA></XML>"
;Call function
ParseXml(xml)
;Show values
i=0
ForEach lTag()
i=i+1
; Debug "Tag (Parent) : " + Str(lTag()\pParentTag)
Debug "Tag (Name) : " + lTag()\vName
Debug "Tag (Value) : " + lTag()\vValue
; Debug "Tag (Level) : " + Str(lTag()\vLevel)
;Tag has attributes ?
If lTag()\pAttr <> 0
ForEach lAttr()
If lAttr()\pTag = i
Debug "Attribute (Name) : " + lAttr()\vName + " = " + lAttr()\vValue
EndIf
Next
EndIf
Next