xml-datei in Structure extrahieren

Anfängerfragen zum Programmieren mit PureBasic.
schleicher
Beiträge: 214
Registriert: 30.03.2014 19:57
Computerausstattung: Purebasic 5.70
Wohnort: 18314 Löbnitz

xml-datei in Structure extrahieren

Beitrag von schleicher »

Ich möchte eine xml-Datei in eine structure extrahieren, bekomme es aber nicht hin.
Die xml-datei ist so aufgebaut :

Code: Alles auswählen

<programme start="20190425175000 +0200" stop="20190425181000 +0200" channel="disneychannel.de">
    <title lang="de">DuckTales: Dagoberts gefährlichste Schätze</title>
    <sub-title lang="de">Zeichentrickserie</sub-title>
    <desc lang="de">Lena nutzt Nicky, um in den Tresorraum zu gelangen, in dem Dagobert all seine gefährlichsten Artefakte aufbewahrt. Doch hat Lena vielleicht endlich genug von Gundel Gaukeleys Manipulationen</desc>
  </programme>
Kann jemand helfen ?
Purebasic 5.51
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: xml-datei in Structure extrahieren

Beitrag von RSBasic »

Hast du schon mit ExtractXMLStructure() probiert? Damit kannst du deinen XML-Code in eine PB-Structure konvertieren. Siehe Beispielcode in der PB-Hilfe.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
schleicher
Beiträge: 214
Registriert: 30.03.2014 19:57
Computerausstattung: Purebasic 5.70
Wohnort: 18314 Löbnitz

Re: xml-datei in Structure extrahieren

Beitrag von schleicher »

Ich habs probiert, doch leider ohne Erfolg
Hier mein Code:

Code: Alles auswählen

Global epgdir.s="C:\Basic.xml"

Enumeration
  #XMLEPG
EndEnumeration

Structure EPG
  Programme.s
  start.s
  stop.s
  channel.s
  title.s
  desc.s
EndStructure

Structure epgresult
  total_results.i
  total_pages.i
  page.i
  List results.EPG()
EndStructure

Global epg.epgresult, Message$



If LoadXML(#XMLEPG, epgdir)
  
  
  If XMLStatus(#XMLEPG) <> #PB_XML_Success
    Message$ = "Error in the XML file:" + Chr(13)
    Message$ + "Message: " + XMLError(#XMLEPG) + Chr(13)
    Message$ + "Line: " + Str(XMLErrorLine(#XMLEPG)) + "   Character: " + Str(XMLErrorPosition(#XMLEPG))
    MessageRequester("Error", Message$)
  EndIf  
  ExtractXMLStructure(MainXMLNode(#XMLEPG), @epg.epgresult, epgresult)
  
  FreeXML(#XMLEPG)
Else
  Debug "xml konnte nicht geladen werden"
EndIf
Purebasic 5.51
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: xml-datei in Structure extrahieren

Beitrag von RSBasic »

Speichere deine XML-Datei neu ab, diesmal aber in UTF-8. Dann meckert er nicht mehr bei Umlaute.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
schleicher
Beiträge: 214
Registriert: 30.03.2014 19:57
Computerausstattung: Purebasic 5.70
Wohnort: 18314 Löbnitz

Re: xml-datei in Structure extrahieren

Beitrag von schleicher »

Die xml-Datei müsste UTF-8 sein, denn die erste Zeile der xml lautet:

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
Die Structure bleibt jedoch leer. Fehlermeldung gibt es keine.
Purebasic 5.51
Andesdaf
Moderator
Beiträge: 2658
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Re: xml-datei in Structure extrahieren

Beitrag von Andesdaf »

ExtractXMLStructure kann keine XML-Attribute auslesen, sondern nur Texte innerhalb von Knoten. PB-Struktur und XML-Struktur müssten außerdem exakt gleich sein. Mach es am Besten selbst, entweder per XMLNodeFromPath oder, indem du über die gesamte Struktur läufst (ChildXMLNode/NextXMLNode).
Win11 x64 | PB 6.00 (x64)
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: xml-datei in Structure extrahieren

Beitrag von RSBasic »

Er konvertiert nur die Knoten in Structure-Elemente und keine Attribute.
D.h. <title>, <sub_title> und <desc> würde er in folgende Struktur importieren:

Code: Alles auswählen

Structure epgresult
  title.s
  sub_title.s
  desc.s
EndStructure
Wenn du auch die Attribute importieren möchtest, musst du selber einen Importer schreiben.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
schleicher
Beiträge: 214
Registriert: 30.03.2014 19:57
Computerausstattung: Purebasic 5.70
Wohnort: 18314 Löbnitz

Re: xml-datei in Structure extrahieren

Beitrag von schleicher »

Andesdaf hat geschrieben:Mach es am Besten selbst, entweder per XMLNodeFromPath oder, indem du über die gesamte Struktur läufst (ChildXMLNode/NextXMLNode).
Diese Methode hatte ich bisher am laufen, doch diese dauert lange, da die xml-Datein doch ziemlich groß sind. Insgesamt fast 26 MB. Deshalb der Gedanke es direkt in eine Structure zu exportieren. Aber nach dieser Erkenntnis :
Andesdaf hat geschrieben:ExtractXMLStructure kann keine XML-Attribute auslesen, sondern nur Texte innerhalb von Knoten.
ist das wohl nicht so möglich.
RSBasic hat geschrieben:Wenn du auch die Attribute importieren möchtest, musst du selber einen Importer schreiben.
Dafür reichen meine Kenntnisse leider nicht aus.
Purebasic 5.51
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: xml-datei in Structure extrahieren

Beitrag von RSBasic »

schleicher hat geschrieben:Diese Methode hatte ich bisher am laufen, doch diese dauert lange, da die xml-Datein doch ziemlich groß sind. Insgesamt fast 26 MB. Deshalb der Gedanke es direkt in eine Structure zu exportieren.
Dauert es deshalb so lange, weil du vielleicht mit ReadString() gearbeitet hast? Wenn du die XML-Datei mit ReadData() aufeinmal in den Speicher lädst und im schnellen Speicher die einzelnen Knoten und Attribute importierst, dann sollte es nicht so lange dauern.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
schleicher
Beiträge: 214
Registriert: 30.03.2014 19:57
Computerausstattung: Purebasic 5.70
Wohnort: 18314 Löbnitz

Re: xml-datei in Structure extrahieren

Beitrag von schleicher »

Readstring() habe ich nicht verwendet.
RSBasic hat geschrieben:Wenn du die XML-Datei mit ReadData() aufeinmal in den Speicher lädst und im schnellen Speicher die einzelnen Knoten und Attribute importierst, dann sollte es nicht so lange dauern.
Das hatte ich bisher noch nicht probiert. Das versuche ich mal.Mal sehen ob ich das hinbekomme.

Bisher hatte ich das so :

Code: Alles auswählen

Structure epg
  sendername.s
  start_stop.s
  titel.s
  genre.s
  year.s
  startdatum.s
  stopdatum.s
  freigabe.s
  beschreibung1.s
  beschreibung2.s
  beschreibung3.s
  beschreibung4.s
  beschreibung5.s
  beschreibung6.s
  beschreibung7.s
  beschreibung8.s
  start.s
  stop.s
EndStructure
Global NewList epg.epg()

Enumeration
  #XML
EndEnumeration

Global tzi.TIME_ZONE_INFORMATION
Global Zeitversatz = GetTimeZoneInformation_(@tzi.TIME_ZONE_INFORMATION)
Global epgdir.s="C:\Users\Mike\ECC\et7500\EPG\"

Declare xml_to_struc()
Declare Fill_struc(*Currentnode,Currentsublevel)
Declare.s date_time_epg(datestring.s, wert)

xml_to_struc()
If ListSize(epg())>0
  ForEach epg()
  Debug "Sendername = "+epg()\sendername
  Debug "Titel = "+epg()\titel
  Debug "Start = "+epg()\start
  Debug "Startdatum = "+epg()\startdatum
  Debug "Stopdatum = "+epg()\stopdatum
  Debug "Ende = "+epg()\stop
  Debug "Genre = "+epg()\genre
  Debug "Freigabe = "+epg()\freigabe
  Debug "Jahr = "+epg()\year
  Debug "Beschreibung = "+epg()\beschreibung1+epg()\beschreibung2+epg()\beschreibung3+epg()\beschreibung4+epg()\beschreibung5+epg()\beschreibung6+epg()\beschreibung7+epg()\beschreibung8
 Next
EndIf

Procedure xml_to_struc()
  Protected Filename$, 
            Currentsublevel=0
  Protected Message$, *MainNode, Event, i
  
  If ExamineDirectory(0, epgdir, "*.xml")
    While NextDirectoryEntry(0)
      If DirectoryEntryType(0)=#PB_DirectoryEntry_File 
        Filename$=DirectoryEntryName(0)
        If FileName$ <> ""
          
          If LoadXML(#XML, epgdir+FileName$)
            FormatXML(#XML,#PB_XML_ReduceNewline|#PB_XML_CutNewline )
            
            If XMLStatus(#XML) <> #PB_XML_Success
              Message$ = "Error in the XML file:" + Chr(13)
              Message$ + "Message: " + XMLError(#XML) + Chr(13)
              Message$ + "Line: " + Str(XMLErrorLine(#XML)) + "   Character: " + Str(XMLErrorPosition(#XML))
              MessageRequester("Error", Message$)
              status_xml=0
            EndIf
            
            
            *MainNode = MainXMLNode(#XML)      
            If *MainNode
              Fill_struc(*Mainnode, Currentsublevel)
            EndIf
            FreeXML(#XML)
          Else
            MessageRequester("Error", "The EPG-file cannot be opened.")
          EndIf
        EndIf
      EndIf
    Wend
    FinishDirectory(0)
  Else
    MessageRequester("Error", "Can`t open "+epgdir, #PB_MessageRequester_Error )
  EndIf
  
EndProcedure


Procedure Fill_struc(*Currentnode,Currentsublevel)
  Protected Text$, *ChildNode, Text1$
  Protected  prog_start_end_name.s, anzahl, dat.s, time.s, date_time_start.s, date_time_end.s, date_time_end1.s, prog_name.s, prog_genre.s, prog_genre1.s, prog_text.s, Text_ori.s, leng, y, datum.s, zeit.s, datum_ende.s
  Protected  prog_text1.s, prog_text2.s, prog_text3.s, prog_text4.s,prog_text5.s, prog_text6.s, prog_text7.s,prog_text8.s, jahr.s, channelid.s, channelname.s ,  year_.s, freigabe.s, year_epg.s, channel_.s, x, channel_id.s
  Protected  diff_to_utc.s, oldchannel.s
  
  If XMLNodeType(*CurrentNode) = #PB_XML_Normal
    
    Text$ = GetXMLNodeName(*CurrentNode) 
    
    If ExamineXMLAttributes(*CurrentNode)
      While NextXMLAttribute(*CurrentNode)
        
        Text$ + XMLAttributeName(*CurrentNode) + " "  + XMLAttributeValue(*CurrentNode) +" "+GetXMLNodeText(*CurrentNode)
        
        If FindString(Text$, "  ")   
          Text$=ReplaceString(Text$, "  ", " ")
        EndIf
        If FindString(Text$, "   ")
          Text$=ReplaceString(Text$, "   ", " ")
        EndIf
        If FindString(Text$, "    ")
          Text$=ReplaceString(Text$, "    ", " ")
        EndIf
        If FindString(Text$, "     ")
          Text$=ReplaceString(Text$, "     ", " ")
        EndIf
        
        If FindString(Text$, "channelid")
          channel_id=Trim(RemoveString(Text$, "channelid"))
          
        ElseIf FindString(Text$, "display-namelang") 
          
          channelname=LCase(Trim(Mid(Text$, 20)))
          channelname=ReplaceString(channelname, ".", " ")
          
        ElseIf FindString(Text$, "programmestart") And FindString(Text$, "stop") And FindString(Text$, "channel")
          
          prog_start_end_name=Trim(Text$)
          diff_to_utc=Mid(prog_start_end_name, 31, 5)
          If Left(diff_to_utc, 1)="+"
            diff_to_utc=Mid(diff_to_utc, 3, 1)
          ElseIf Left(diff_to_utc, 1)="-"
            diff_to_utc=Mid(diff_to_utc, 1, 1)+Mid(diff_to_utc, 3, 1)
          EndIf
          
          AddElement(epg())
          
          channelid=Mid(Text$, 70)
          channelid=Trim(channelid)
          date_time_start=Trim(Mid(Text$, 15, 14))
          date_time_start=date_time_epg(date_time_start, Val(diff_to_utc))
          epg()\startdatum=StringField(date_time_start, 1,"|")
          date_time_start=StringField(date_time_start, 2, "|")
          date_time_end=Trim(Mid(Text$, 41, 14))
          date_time_end=date_time_epg(date_time_end, Val(diff_to_utc))
          date_time_end1=StringField(date_time_end, 2, "|")
          datum_ende=StringField(date_time_end, 1, "|")
          channel_=Trim(Mid(Text$, 70))
          epg()\start_stop=prog_start_end_name
          epg()\start=date_time_start
          epg()\sendername=channel_
          epg()\stop=date_time_end1
          epg()\stopdatum=datum_ende
          
          
        ElseIf Mid(Text$, 1, 9)="titlelang"
          epg()\titel=Mid(Text$, 14)
          
        ElseIf Mid(Text$, 1, 3)="sub" 
          prog_genre=RemoveString(Text$, " ")
          prog_genre=RemoveString(prog_genre, "(")
          prog_genre=RemoveString(prog_genre, ")")
          prog_genre=ReplaceString(prog_genre, "]", "|")
          prog_genre=ReplaceString(prog_genre, "[", "|")
          prog_genre1=StringField(prog_genre, 2, "|")
          jahr=StringField(prog_genre, 3, "|")
          freigabe=StringField(prog_genre, 4, "|")
          epg()\freigabe=freigabe
          epg()\genre=prog_genre1
          epg()\year=jahr
          
        ElseIf Mid(Text$, 1, 4)="desc"
          
          prog_text =Trim(Mid(Text$, 13)) 
          
          If FindString(prog_text, Chr(10))
            prog_text=RemoveString(prog_text, Chr(10))
          EndIf
          If FindString(prog_text, Chr(13))
            prog_text=RemoveString(prog_text, Chr(13))  
          EndIf
          
          prog_text1=Mid(prog_text, 1, 200)
          epg()\beschreibung1=prog_text1
          prog_text2=Mid(prog_text, 201, 200)
          epg()\beschreibung2=prog_text2
          prog_text3=Mid(prog_text, 401, 200)
          epg()\beschreibung3=prog_text3
          prog_text4=Mid(prog_text, 601 , 200)
          epg()\beschreibung4=prog_text4
          prog_text5=Mid(prog_text, 801 , 200)
          epg()\beschreibung5=prog_text5
          prog_text6=Mid(prog_text, 1001 , 200)
          epg()\beschreibung6=prog_text6
          prog_text7=Mid(prog_text, 1201, 200)
          epg()\beschreibung7=prog_text7
          prog_text8=Mid(prog_text, 1401, 200)
          epg()\beschreibung8=prog_text8
          
        EndIf
      Wend
    EndIf
    
    
    
    *ChildNode = ChildXMLNode(*CurrentNode)
    
    While *ChildNode <> 0
      CurrentSublevel + 1
      Fill_struc(*ChildNode, Currentsublevel) 
      *ChildNode = NextXMLNode(*ChildNode)
    Wend 
    
  EndIf
  
EndProcedure

Procedure.s date_time_epg(datestring.s, wert)
  Protected jahr.s, monat.s, tag.s, stunde.s, minute.s, movie.s, datum_zeit.s, stunde_s, datum.s, zeit.s, date_time_unix, versatz
  movie=datestring
  jahr=Mid(movie, 0, 4)
  monat=Mid(movie, 5, 2)
  tag=Mid(movie, 7, 2)
  stunde=Mid(movie, 9, 2)
  minute=Mid(movie, 11, 2)
  datum=tag+"."+monat+"."+jahr
  zeit=stunde+":"+minute+":00"
  date_time_unix=ParseDate("%dd.%mm.%yyyy%hh:%ii:%ss", datum+zeit)
  versatz=wert-Zeitversatz
  date_time_unix=AddDate(date_time_unix, #PB_Date_Hour, -versatz)
  datum=FormatDate("%dd.%mm.%yyyy", date_time_unix)
  zeit=FormatDate("%hh:%ii", date_time_unix)
  
  datum_zeit.s=datum+"|"+zeit
  ProcedureReturn datum_zeit.s
  
EndProcedure
Zuletzt geändert von schleicher am 20.04.2019 11:52, insgesamt 1-mal geändert.
Purebasic 5.51
Antworten