Hallo Paradise,
ihr werdet es alle irgendwie kennen, das man die ganze Zeit ohne Probleme herum Coded, dann aber irgendwann an ein eigentlich total Simples Problem kommt, und euer Hirn einfach dicht macht.
So auch grad bei mir... Normalerweise fällt mir die lösung beim Aufstehen oder auf'm Pott ein. Diesmla leider nicht... Und ich bin schon einige Tage dran... xD
Folgendermaßen sieht es aus:
Ich bekomme von einer Firefox Extension per XML Daten an einen Port gesendet. Dies funktioniert auch alles Tadellos. Ich kann die Daten lesen, und die Informationen dazu auch in Strukturen speichern. Alles nicht das Ding. Zur veranschaulichung einmal einer dieser XML Datensätze:
An sich ist das Auslesen an dieser Stelle kein Problem. Habe ich ja soweit auch schon vorliegen. Das Problem ist hier, das ich per Endlosschliefe alle entry Nodes durchgehen muss, da abgesehen von dem "Solar Sattelite" Eintrag keine Einträge erstellt werden die eine "amount" von 0 haben.
Im moment mache ich das ganze auf folgendem Weg:
Spoiler anzeigen
Wie das abläuft sollte soweit ja klar sein. (Die ParseXML_PlanetInfo ist übrigens gekürzt. Sonst hätte es nicht in den Post gepasst.)
Allerdings bin ich davon überzeugt, das dies auch ein wenig einfacher geht. Ich habe hier in diesem Beispiel grad mal 50% von dem hinzugefügt, das eigentlich noch kommen muss...
Nur wird das ganze immer komplizierter.
Hat jemand eine Idee, das ein wenig zu einfachen?
Grüße,
ryg
ihr werdet es alle irgendwie kennen, das man die ganze Zeit ohne Probleme herum Coded, dann aber irgendwann an ein eigentlich total Simples Problem kommt, und euer Hirn einfach dicht macht.
So auch grad bei mir... Normalerweise fällt mir die lösung beim Aufstehen oder auf'm Pott ein. Diesmla leider nicht... Und ich bin schon einige Tage dran... xD
Folgendermaßen sieht es aus:
Ich bekomme von einer Firefox Extension per XML Daten an einen Port gesendet. Dies funktioniert auch alles Tadellos. Ich kann die Daten lesen, und die Informationen dazu auch in Strukturen speichern. Alles nicht das Ding. Zur veranschaulichung einmal einer dieser XML Datensätze:
XML-Quellcode
- <?xml version="1.0" encoding="UTF-8"?>
- <planetinfos xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="planetinfo.xsd">
- <header version="2.6" universe="Jupiter" debug="true" language="german" content_type="planetinfo"/>
- <planetinfo playername="xxx" playerid="111111" planetname="Atom" moon="false" galaxy="1" system="2" planet="3">
- <entry name="Metal" amount="46026"/>
- <entry name="Crystal" amount="46006"/>
- <entry name="Deuterium" amount="24340"/>
- <entry name="Energy" amount="2495"/>
- <entry name="Metal Mine" amount="16"/>
- <entry name="Crystal Mine" amount="15"/>
- <entry name="Deuterium Synthesizer" amount="10"/>
- <entry name="Solar Plant" amount="18"/>
- <entry name="Fusion Reactor" amount="7"/>
- <entry name="Solar Satellite" amount="0"/>
- <entry name="Metal Storage" amount="4"/>
- <entry name="Crystal Storage" amount="3"/>
- <entry name="Deuterium Tank" amount="2"/>
- </planetinfo>
- </planetinfos>
An sich ist das Auslesen an dieser Stelle kein Problem. Habe ich ja soweit auch schon vorliegen. Das Problem ist hier, das ich per Endlosschliefe alle entry Nodes durchgehen muss, da abgesehen von dem "Solar Sattelite" Eintrag keine Einträge erstellt werden die eine "amount" von 0 haben.
Im moment mache ich das ganze auf folgendem Weg:
VB.NET-Quellcode
- Imports System.Xml
- Imports System.Xml.Serialization
- Imports System.IO
- Imports ogTypes
- Public Class clsParseXML
- Private ParseType As New ogTypeParsePlanetinfo
- Private GTStrings() As String
- Private sPageType As String
- 'Seitentypen der PlanetInfo XML Seite der GT-Extension
- 'ress, faci, rese, fleet, def
- Private sPlanetInfoPage As String
- ' Öffentliche Klassenvariablen, Ändern des Pfades nach der Instanziierung möglich
- Public XMLData As String
- Sub New(ByVal Data As String)
- XMLData = Data
- ' hier nehme ich in der ersten Zeile 2 aufeinanderfolgende Leerzeichen weg
- ' das wird hier nur einmal ausgeführt.
- 'XMLData = Replace(XMLData, " ", "", 1, 1)
- 'Ich habe das hier ein wenig Umgeschrieben, da es (so wie ich das in einem Testfall mitbekommen habe)
- 'auch mal sein kann, das nicht nur 2 Stellen sondern auch mal nur eine oder 3 auftreten können.^^
- 'Und diese Lösung ist für all diese Fälle geeignet =D
- XMLData = "<" & SplitString(XMLData, "<", 2)
- End Sub
- ''' <summary>
- ''' Kategorisiert die einzelnen Planetinfo Daten und fügt diese in ein Parse-Struct
- ''' </summary>
- ''' <remarks>09.04.2011 - ryg</remarks>
- Sub ParseXML_PlanetInfo()
- Dim xmlDoc As New XmlDocument
- Dim ParseNodes As XmlNodeList
- Dim ParseNode As XmlNode
- Dim rawData As String
- rawData = XMLData
- xmlDoc.LoadXml(rawData)
- ParseNodes = xmlDoc.GetElementsByTagName("header")
- For Each ParseNode In ParseNodes
- ParseType.Uni = ParseNode.Attributes("universe").Value
- Next
- If Not ParseType.Uni = ogProfile.Uni.UniName Then
- ' An dieser Stelle sollte zusätzlich geprüft werden, ob ein Profil für die Daten vorhanden ist.
- '
- '
- '
- MsgBox(getLngTxt("XMLParse", "WrongUni"), MsgBoxStyle.Critical)
- Exit Sub
- End If
- ParseNodes = Nothing
- ParseNodes = xmlDoc.GetElementsByTagName("planetinfo")
- For Each ParseNode In ParseNodes
- 'Spielername auslesen
- ParseType.OwnerName = ParseNode.Attributes("playername").Value
- 'Planetenname auslesen
- ParseType.Planet.Planet.Name = ParseNode.Attributes("planetname").Value
- 'Koordinaten des Planeten auslesen
- ParseType.Planet.Koords.Galaxie = ParseNode.Attributes("galaxy").Value
- ParseType.Planet.Koords.System = ParseNode.Attributes("system").Value
- ParseType.Planet.Koords.Number = ParseNode.Attributes("planet").Value
- 'Hier wird geprüft ob es sich hierbei um einen Planeten oder Mond handelt
- If CBool(ParseNode.Attributes("moon").Value) = False Then
- ParseType.Planet.Planet.Name = ParseNode.Attributes("planetname").Value
- Else
- ParseType.Planet.Moon.Name = ParseNode.Attributes("planetname").Value
- End If
- Next
- ParseNodes = Nothing
- ParseNodes = xmlDoc.GetElementsByTagName("officer")
- sPlanetInfoPage = ""
- For Each ParseNode In ParseNodes
- Try
- If Not ParseNode.Attributes("name").Value = vbNullString Then
- ParseXML_Overview()
- Exit Sub
- End If
- Catch ex As Exception
- End Try
- Next
- ParseNodes = Nothing
- ParseNodes = xmlDoc.GetElementsByTagName("entry")
- sPlanetInfoPage = ""
- For Each ParseNode In ParseNodes
- '#####################################################
- 'Ermitteln der Ressourcen
- 'Energie wäre zwar auch möglich macht aber keinen Sinn, da wir das lieber mit hilfe der
- 'Gebäude und Forschungen errechnen =D
- If ParseNode.Attributes("name").Value = "Metal" Then
- ParseType.Planet.Planet.Supplies.Metal = ParseNode.Attributes("amount").Value
- End If
- If ParseNode.Attributes("name").Value = "Crystal" Then
- ParseType.Planet.Planet.Supplies.Crystal = ParseNode.Attributes("amount").Value
- End If
- If ParseNode.Attributes("name").Value = "Deuterium" Then
- ParseType.Planet.Planet.Supplies.Deuterium = ParseNode.Attributes("amount").Value
- End If
- '#####################################################
- 'Ermitteln der Gebäude (Ressourcen)
- If ParseNode.Attributes("name").Value = "Metal Mine" Then
- ParseType.Planet.Planet.Resources.MetalMine = ParseNode.Attributes("amount").Value
- sPlanetInfoPage = "ress"
- End If
- If ParseNode.Attributes("name").Value = "Crystal Mine" Then
- ParseType.Planet.Planet.Resources.CrystalMine = ParseNode.Attributes("amount").Value
- sPlanetInfoPage = "ress"
- End If
- If ParseNode.Attributes("name").Value = "Deuterium Synthesizer" Then
- ParseType.Planet.Planet.Resources.DeuteriumSynthesizer = ParseNode.Attributes("amount").Value
- sPlanetInfoPage = "ress"
- End If
- If ParseNode.Attributes("name").Value = "Solar Plant" Then
- ParseType.Planet.Planet.Resources.SolarPlant = ParseNode.Attributes("amount").Value
- sPlanetInfoPage = "ress"
- End If
- If ParseNode.Attributes("name").Value = "Fusion Reactor" Then
- ParseType.Planet.Planet.Resources.FusionReactor = ParseNode.Attributes("amount").Value
- sPlanetInfoPage = "ress"
- End If
- If ParseNode.Attributes("name").Value = "Solar Satellite" Then
- ParseType.Planet.Planet.Resources.SolarSatellite = ParseNode.Attributes("amount").Value
- ' An dieser Stelle wird der Seitenname NICHT übergeben! Könnte ja auch die Flottenseite sein.
- End If
- If ParseNode.Attributes("name").Value = "Metal Storage" Then
- ParseType.Planet.Planet.Resources.MetalStorage = ParseNode.Attributes("amount").Value
- sPlanetInfoPage = "ress"
- End If
- If ParseNode.Attributes("name").Value = "Crystal Storage" Then
- ParseType.Planet.Planet.Resources.CrystalStorage = ParseNode.Attributes("amount").Value
- sPlanetInfoPage = "ress"
- End If
- If ParseNode.Attributes("name").Value = "Deuterium Tank" Then
- ParseType.Planet.Planet.Resources.DeuteriumTank = ParseNode.Attributes("amount").Value
- sPlanetInfoPage = "ress"
- End If
- '#####################################################
- 'Ermitteln der Gebäude (Facilities)
- If ParseNode.Attributes("name").Value = "Robotics Factory" Then
- ParseType.Planet.Planet.Facilities.RoboticFactory = ParseNode.Attributes("amount").Value
- sPlanetInfoPage = "faci"
- End If
- If ParseNode.Attributes("name").Value = "Nanite Factory" Then
- ParseType.Planet.Planet.Facilities.RoboticFactory = ParseNode.Attributes("amount").Value
- sPlanetInfoPage = "faci"
- End If
- If ParseNode.Attributes("name").Value = "Shipyard" Then
- ParseType.Planet.Planet.Facilities.RoboticFactory = ParseNode.Attributes("amount").Value
- sPlanetInfoPage = "faci"
- End If
- If ParseNode.Attributes("name").Value = "Research Lab" Then
- ParseType.Planet.Planet.Facilities.RoboticFactory = ParseNode.Attributes("amount").Value
- sPlanetInfoPage = "faci"
- End If
- If ParseNode.Attributes("name").Value = "Terraformer" Then
- ParseType.Planet.Planet.Facilities.RoboticFactory = ParseNode.Attributes("amount").Value
- sPlanetInfoPage = "faci"
- End If
- If ParseNode.Attributes("name").Value = "Alliance Depot" Then
- ParseType.Planet.Planet.Facilities.RoboticFactory = ParseNode.Attributes("amount").Value
- sPlanetInfoPage = "faci"
- End If
- If ParseNode.Attributes("name").Value = "Missile Silo" Then
- ParseType.Planet.Planet.Facilities.RoboticFactory = ParseNode.Attributes("amount").Value
- sPlanetInfoPage = "faci"
- End If
- Next
- End Sub
- Sub ParseXML_Allypage()
- End Sub
- ''' <summary>
- ''' Erkennt die Hauptkategorie der XML Daten und startet die jehweiligen Parser
- ''' </summary>
- ''' <remarks>09.04.2011 - ryg</remarks>
- Public Sub ParseXML_Read()
- Dim xmlDoc As New XmlDocument
- Dim ParseNodes As XmlNodeList
- Dim ParseNode As XmlNode
- Dim rawData As String
- '#######################################
- '#######################################
- '## TEST
- ogProfile.Uni.UniName = "Jupiter"
- '#######################################
- '#######################################
- rawData = XMLData
- xmlDoc.LoadXml(rawData)
- ParseNodes = xmlDoc.GetElementsByTagName("header")
- For Each ParseNode In ParseNodes
- sPageType = ParseNode.Attributes("content_type").Value
- Select Case sPageType
- Case "planetinfo"
- ParseXML_PlanetInfo()
- Case "allypage"
- ParseXML_Allypage()
- Case "reports"
- ParseXML_Reports()
- Case "player_stats"
- ParseXML_PlayerStats()
- Case "ally_stats"
- ParseXML_AllyStats()
- End Select
- Next
- 'Bis hier wurden die Daten ausgelesen.
- 'Nun kommt das Aktualisieren der Structures.
- '(An dieser Stelle wird das Updaten für Deaktivierte Profile noch NICHT berücksichtigt.
- ParseXML_UpdateStruct()
- End Sub
- End Class
Allerdings bin ich davon überzeugt, das dies auch ein wenig einfacher geht. Ich habe hier in diesem Beispiel grad mal 50% von dem hinzugefügt, das eigentlich noch kommen muss...
Nur wird das ganze immer komplizierter.
Hat jemand eine Idee, das ein wenig zu einfachen?
Grüße,
ryg