Gelöst - XML lesen

Anfängerfragen zum Programmieren mit PureBasic.
_v4
Beiträge: 26
Registriert: 16.11.2012 13:36

Gelöst - XML lesen

Beitrag von _v4 »

Würde gerne aus einem beliebigen XML-File einen Wert lesen. Die Daten sind komplett unterschiedlich aufgebaut, aber die Tags mit Werten immer gleich.

Beispiel:

Code: Alles auswählen

... anderer Dateiinhalt ...
<zu:lesendesTag>Enthaltene Werte 123</zu:lesendesTag>
... anderer Dateiinhalt ...
Jetzt kann es sein, dass dieses Tag an beliebiger Stelle steht (d.h. auch unterschiedlich "tief" in der Struktur). Deshalb sollte nach dem Tag "zu:lesendesTag" gesucht werden.

Wie lässt sich dies realisieren (Kam leider mit dem Beispiel aus der Hilfe nicht so zurecht) ?

Vielen Dank schonmal!
Zuletzt geändert von _v4 am 16.12.2012 13:53, insgesamt 1-mal geändert.
Benutzeravatar
Thorsten1867
Beiträge: 1360
Registriert: 04.02.2005 15:40
Computerausstattung: [Windows 10 x64] [PB V5.7x]
Wohnort: Kaufbeuren
Kontaktdaten:

Re: XML lesen

Beitrag von Thorsten1867 »

Das sollte mit einem rekursivem Aufruf funktionieren:

Code: Alles auswählen

#XML = 1

Procedure ReadChildNodes(*Node, Tag$)
  *ChildNode = ChildXMLNode(*Node)
  While *ChildNode <> 0
    If GetXMLNodeName(*ChildNode) = Tag$ ; Tag gefunden
      Debug GetXMLNodeText(*ChildNode)
    EndIf
    If XMLChildCount(*ChildNode)
      ReadChildNodes(*ChildNode, Tag$)
    EndIf
    *ChildNode = NextXMLNode(*ChildNode)
  Wend
EndProcedure

; Suche <Test> in Datei "Test.xml"
If LoadXML(#XML, "Test.xml")
  *MainNode = MainXMLNode(#XML)
  If *MainNode
    ReadChildNodes(*MainNode, "Test")
  EndIf
EndIf
[edit]Tipp von Kiffi[/edit]
Zuletzt geändert von Thorsten1867 am 12.12.2012 16:29, insgesamt 1-mal geändert.
Download of PureBasic - Module
Download of PureBasic - Programmes

[Windows 11 x64] [PB V6]

Bild
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: XML lesen

Beitrag von Kiffi »

@Thorsten: :allright:

kleiner Verbesserungsvorschlach:

Code: Alles auswählen

<root>
	<node>1.ebene1</node>
	<node>1.ebene2</node>
	<node>1.ebene3</node>
	<node>
		<node>2.ebene1</node>
		<node>2.ebene2</node>
		<node>2.ebene3</node>
	</node>
</root>
um die Nodes der 2ten Ebene im obigen XML auch noch zu lesen, sollte
ReadChildNodes() auch aufgerufen werden, wenn ein Node gefunden wird.

Code: Alles auswählen

Procedure ReadChildNodes(*Node, Tag$)
  *ChildNode = ChildXMLNode(*Node)
  While *ChildNode <> 0
    If GetXMLNodeName(*ChildNode) = Tag$ ; Tag gefunden
      Debug GetXMLNodeText(*ChildNode)
    EndIf
    If XMLChildCount(*ChildNode)
      ReadChildNodes(*ChildNode, Tag$)
    EndIf
    *ChildNode = NextXMLNode(*ChildNode)
  Wend
EndProcedure
Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
helpy
Beiträge: 636
Registriert: 29.08.2004 13:29

Re: XML lesen

Beitrag von helpy »

Hi,

Another example ... will store all found nodes in an array:

Code: Alles auswählen

Procedure XMLNodesFromTagName( *StartNode, TagName.s, Array nodeList.i(1), FreeArray = #True )
	Protected *nChild
	Protected NodeName.s
	
	If FreeArray : FreeArray( nodeList() ) : EndIf
 	If Not *StartNode : ProcedureReturn 0 : EndIf
	
	NodeName = GetXMLNodeName(*StartNode)
	If NodeName = TagName
		If FreeArray
			Dim nodeList.i(0)
		Else
			ReDim nodeList.i(ArraySize(nodeList())+1)
		EndIf
		nodeList.i(ArraySize(nodeList())) = *StartNode
	EndIf
	
	*nChild = ChildXMLNode(*StartNode)
	While *nChild
		XMLNodesFromTagName( *nChild, TagName, nodeList(), #False )
		*nChild = NextXMLNode(*nChild)
	Wend
	
	ProcedureReturn (ArraySize(nodeList()) + 1)
EndProcedure
The procedure scans the whole xml tree for all nodes with the given tagname.
All found nodes are added to an array of type integer.
The procedure will return the amount of found nodes if you call it without the parameter FreeArray (or set to #True).

I did not tested the code!
Hope it will help anyway.

cu,
guido


[EDIT]
UUUUPS ... umgekehrt ist es mir schon passiert, dass ich deutsch im englischen Forum geschrieben habe.

aber englisch im deutschen :D :D :roll: :D :D
[/EDIT]
Zuletzt geändert von helpy am 12.12.2012 19:34, insgesamt 1-mal geändert.
Windows 10
PB Last Final / (Sometimes testing Beta versions)
Benutzeravatar
Thorsten1867
Beiträge: 1360
Registriert: 04.02.2005 15:40
Computerausstattung: [Windows 10 x64] [PB V5.7x]
Wohnort: Kaufbeuren
Kontaktdaten:

Re: XML lesen

Beitrag von Thorsten1867 »

Bei einer unbekannten Anzahl von Ergebnissen würde ich eine LinkedList bevorzugen.

Code: Alles auswählen

#XML = 1

Procedure ReadChildNodes(*Node, Tag$, List result.s())
  *ChildNode = ChildXMLNode(*Node)
  While *ChildNode <> 0
    If GetXMLNodeName(*ChildNode) = Tag$ ; Tag gefunden
      AddElement(result())
      result() = GetXMLNodeText(*ChildNode)
    EndIf
    If XMLChildCount(*ChildNode)
      ReadChildNodes(*ChildNode, Tag$, result())
    EndIf
    *ChildNode = NextXMLNode(*ChildNode)
  Wend
EndProcedure


; Suche <Test> in Datei Test.xml
NewList result.s()
If LoadXML(#XML, "Test.xml")
  *MainNode = MainXMLNode(#XML)
  If *MainNode
    ReadChildNodes(*MainNode, "Test", result())
    ; Ergebnisse anzeigen
    ForEach result()
      Debug "-> " + result()
    Next
  EndIf
EndIf
Download of PureBasic - Module
Download of PureBasic - Programmes

[Windows 11 x64] [PB V6]

Bild
_v4
Beiträge: 26
Registriert: 16.11.2012 13:36

Re: XML lesen

Beitrag von _v4 »

Entschuldigt meine späte Rückschrift. Möchte Euch allen vielmals für eure schnellen & kompetenten Antworten danken. Hilft mir so auf jeden Fall weiter!

Schöne Grüße :)
Antworten