XML Tutorial und Fragen zu XML und PB...

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Bisonte
Beiträge: 2465
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

Das sieht leichter verdaulich aus als ich dachte... Werd ich dann heut abend mal Versuchen umzusetzen.

Dank erstmal... Fragen tauchen bestimmt noch auf... Ich kenn mich doch ;)

Edit: jo begriffen hab ichs ;) nun kommen die fragen ...

Kann man auch so wie man die daten ausliest, daten einfügen, die dann im File dementsprechend gespeichert werden ?
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
Bisonte
Beiträge: 2465
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

So nun hab ich mal eine XML Datei so modifiziert, dass man da wohl unmöglich das Original erkennen kann, wohl aber die Struktur.

Civ4.xml

Code: Alles auswählen

<?xml version="1.0"?>
<!-- edited with XMLSPY v2004 rel. 2 U (http://www.xmlspy.com) by Alex Mantzaris (Firaxis Games) -->
<!-- Sid Meier's Civilization 4 -->
<!-- Copyright Firaxis Games 2005 -->
<!-- -->
<!-- UnitClass Schema -->
<Civ4UnitClassInfos xmlns="x-schema:CIV4UnitSchema.xml">
	<UnitClassInfos>
		<UnitClassInfo>
			<Type>UNITCLASS_GUMMIBAER</Type>
			<Description>TXT_KEY_UNIT_SCOUT</Description>
			<iMaxGlobalInstances>-122</iMaxGlobalInstances>
			<iMaxTeamInstances>-13</iMaxTeamInstances>
			<iMaxPlayerInstances>-14</iMaxPlayerInstances>
			<iInstanceCostModifier>15</iInstanceCostModifier>
			<DefaultUnit>UNIT_SCOUT</DefaultUnit>
		</UnitClassInfo>
		<UnitClassInfo>
			<Type>UNITCLASS_LAKRITZ</Type>
			<Description>TXT_KEY_UNIT_LION</Description>
			<iMaxGlobalInstances>-123</iMaxGlobalInstances>
			<iMaxTeamInstances>-16</iMaxTeamInstances>
			<iMaxPlayerInstances>-17</iMaxPlayerInstances>
			<iInstanceCostModifier>18</iInstanceCostModifier>
			<DefaultUnit>UNIT_LION</DefaultUnit>
		</UnitClassInfo>
		<UnitClassInfo>
			<Type>UNITCLASS_BROETCHEN</Type>
			<Description>TXT_KEY_UNIT_BEAR</Description>
			<iMaxGlobalInstances>-125</iMaxGlobalInstances>
			<iMaxTeamInstances>-12</iMaxTeamInstances>
			<iMaxPlayerInstances>-17</iMaxPlayerInstances>
			<iInstanceCostModifier>500</iInstanceCostModifier>
			<DefaultUnit>UNIT_BEAR</DefaultUnit>
		</UnitClassInfo>
	</UnitClassInfos>
</Civ4UnitClassInfos>
Nun der Programmabschnitt (kiffi's Help), der das auslesen soll :

Code: Alles auswählen

Structure Civ4UnitClassInfos
  Wert.s[7]
EndStructure

Global Dim Civ4UnitClassInfosPfad.s(6)
Global NewList Civ4UnitClassInfos.Civ4UnitClassInfos()

Civ4UnitClassInfosPfad(0)="Type"
Civ4UnitClassInfosPfad(1)="Description"
Civ4UnitClassInfosPfad(2)="iMaxGlobalInstances"
Civ4UnitClassInfosPfad(3)="iMaxTeamInstances"
Civ4UnitClassInfosPfad(4)="iMaxPlayerInstances"
Civ4UnitClassInfosPfad(5)="iInstanceCostModifier"
Civ4UnitClassInfosPfad(6)="DefaultUnit"


oXML = LoadXML(#PB_Any, "C:\CIV4.xml")


If oXML

  NodeCounter = 0

  Repeat
   
    oNodes = XMLNodeFromPath(RootXMLNode(oXML), "Civ4UnitClassInfos/UnitClassInfos/UnitClassInfo[" + Str(NodeCounter) + "]")

    If oNodes = 0 
      Break 
    EndIf
    
    AddElement(Civ4UnitClassInfos())
    
    For i=0 To 6
    oNode = XMLNodeFromPath(oNodes, Civ4UnitClassInfosPfad(i))
    
    If oNode
      Civ4UnitClassInfos()\Wert[i] = GetXMLNodeText(oNode)
    EndIf

    Next i
  
    NodeCounter + 1
   
  ForEver    

  FreeXML(oXML)
 
EndIf

ForEach Civ4UnitClassInfos()
  Debug Civ4UnitClassInfos()\Wert[0]
Next

Debug CountList(Civ4UnitClassInfos())
Nun ein Problem : Der erste Eintrag (Also GUMMIBAER) wird immer 2x angezeigt, bzw ist in der LL 2x vorhanden. Siehe DEBUG Ausgabe.
Es sollten auch nur 3 Einträge da sein, aber es sind 4. Was ist da los ?
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

Hallo Bisonte,

sorry, my fault. Lass den NodeCounter mit 1 anfangen und nicht mit 0.

Grüße ... Kiffi

// Edit: Ich korrigiere das in meinem Posting
a²+b²=mc²
Benutzeravatar
Bisonte
Beiträge: 2465
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

*Klatschankopp*

da haett ich vielleicht auch selber drauf kommen müssen ;)
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
Bisonte
Beiträge: 2465
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

Und noch ne Frage :

Code: Alles auswählen

			
<Type>UNIT_LION</Type>
<UniqueNames/>
<Special>NONE</Special>
<Capture>NONE</Capture>
Wie man sieht, hat <UniqueNames/> irgendwie nicht das gleiche Schema wie die anderen....

Wie fängt man sowas ab bzw, was macht man mit soetwas. Oder braucht man sich darum nicht zu kümmern ?
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

Bisonte hat geschrieben:Oder braucht man sich darum nicht zu kümmern ?
Darum brauchst Du Dich nicht gesondert zu kümmern. Das ist nur die
korrekte Kurzschreibweise für einen Node mit leerem Text.
GetXMLNodeText() liefert in diesem Fall dann einen Leerstring zurück.

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
Bisonte
Beiträge: 2465
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

Vielen Dank für prompte Antwort... Na dann muss ich ja jetzt mal loslegen ;)
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
Bisonte
Beiträge: 2465
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

Und nun hab ich wieder ein Problem...

Dies sei die XML Datei:

Code: Alles auswählen

<Civ4UnitInfos>
	<UnitInfos>
		<UnitInfo>
			<Type>UNIT_COLONIST</Type>
			<Class>UNITCLASS_COLONIST</Class>
			<UnitAIs>
				<UnitAI>
					<UnitAIType>UNITAI_COLONIST</UnitAIType>
					<bUnitAI>1</bUnitAI>
				</UnitAI>
				<UnitAI>
					<UnitAIType>UNITAI_WORKER</UnitAIType>
					<bUnitAI>2</bUnitAI>
				</UnitAI>
			</UnitAIs>					
		</UnitInfo>
		<UnitInfo>
			<Type>UNIT_INDENTURED_SERVANT</Type>
			<Class>UNITCLASS_INDENTURED_SERVANT</Class>
			<UnitAIs>
				<UnitAI>
					<UnitAIType>UNITAI_COLONIST</UnitAIType>
					<bUnitAI>3</bUnitAI>
				</UnitAI>
				<UnitAI>
					<UnitAIType>UNITAI_WORKER</UnitAIType>
					<bUnitAI>4</bUnitAI>
				</UnitAI>
			</UnitAIs>					
		</UnitInfo>
	</UnitInfos>
</Civ4UnitInfos>
Ich möchte jetzt die Daten von dem zweiten Unternode des zweiten Nodes auslesen.
Aber was ich auch anstelle, ich krieg das Ding nicht zu fassen.

Also Civ4UnitInfos/UnitInfos/UnitInfo/UnitAIs/UnitAI/bUnitAI
vom UnitInfo/Type = UNIT_INDENTURED_SERVANT und
dann vom UnitAIType = UNITAI_WORKER.
Also würd ich gern den Wert 4 auslesen.

An den zweiten Node komme ich ja ran, aber dann kommt wieder eine Verschachtelung, und da krieg ich nur den 1. also UNITAI_COLONIST zu fassen.

Ich komm da einfach nicht weiter...

Edit: ah... hab ich sepp doch den code vergessen...

Code: Alles auswählen

Rootnode.s = "Civ4UnitInfos/UnitInfos/UnitInfo"
node1.s = "Type"
ident1.s = "UNIT_INDENTURED_SERVANT"
node2.s = "UnitAIs/UnitAI/UnitAIType"
ident2.s = "UNITAI_WORKER"
changenode.s = "bUnitAI"

  
oXML = LoadXML(#PB_Any,"c:\xmlfile.xml")

If oXML

  WurzelKnoten = RootXMLNode(oXML)
      
  NodeCounter = 1
  NodeCounter2 = 1

  Repeat

    Knoten = XMLNodeFromPath(WurzelKnoten, Rootnode+"[" + Str(NodeCounter) + "]")
    
    ;Debug "Knoten "+Rootnode+"[" + Str(NodeCounter) + "]"

      
    If Knoten=0
      Break
    EndIf

    Knoten1 = XMLNodeFromPath(Knoten, node1)

    If GetXMLNodeText(Knoten1) =  ident1

      Debug "Inhalt Knoten1 ("+node1+")= "+GetXMLNodeText(Knoten1)
      
      Knoten2 = XMLNodeFromPath(Knoten, node2)
      
      Debug GetXMLNodeText(Knoten2)
      
      
    EndIf
  
    NodeCounter + 1
    
  ForEver
  
FreeXML(oXML)

EndIf
Ist klar, dass der Code nur den UNITAI_COLONIST anzeigt, aber ich kriegs nicht hin innerhalb des Unterknotens weiterzuspringen....
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
Bisonte
Beiträge: 2465
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

Jetzt hab ich es hinbekommen

Da muss man doch erstmal schnallen, das dieses [10] im Pfad den 10. Node
bedeutet.

Also sieht der Pfad bei der Abfrage so aus:

Civ4UnitInfos/UnitInfos/UnitInfo[2]/UnitAIs/UnitAI/bUnitAI[2]

das man das auch ineinander schachteln kann, war mir nicht bekannt.
Ist auch schwer aus der Hilfe zu erkennen.
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
Bisonte
Beiträge: 2465
Registriert: 01.04.2007 20:18

Beitrag von Bisonte »

Erfolgsmeldung zurück !

Ich hatte da leicht was übersehen.

Also wieder die Frage..:

Wie bekomme ich mit sowenig Abfragen wie möglich einen bestimmten
NodeText ausgelesen, der an Bedingungen geknüpft ist ?

Also in dem Falle der XML Datei von oben:

den Wert aus bUnitAI von UNIT_INDENTURED_SERVANT ... UNITAI_WORKER.
Also 4 ?

Und ... was mach ich wenn es noch tiefer geschachtelt ist ?
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Antworten