Seite 1 von 2

xml-datei in Structure extrahieren

Verfasst: 19.04.2019 13:44
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 ?

Re: xml-datei in Structure extrahieren

Verfasst: 19.04.2019 13:46
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.

Re: xml-datei in Structure extrahieren

Verfasst: 19.04.2019 13:59
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

Re: xml-datei in Structure extrahieren

Verfasst: 19.04.2019 14:06
von RSBasic
Speichere deine XML-Datei neu ab, diesmal aber in UTF-8. Dann meckert er nicht mehr bei Umlaute.

Re: xml-datei in Structure extrahieren

Verfasst: 19.04.2019 14:36
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.

Re: xml-datei in Structure extrahieren

Verfasst: 19.04.2019 16:02
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).

Re: xml-datei in Structure extrahieren

Verfasst: 19.04.2019 16:03
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.

Re: xml-datei in Structure extrahieren

Verfasst: 20.04.2019 09:25
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.

Re: xml-datei in Structure extrahieren

Verfasst: 20.04.2019 09:28
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.

Re: xml-datei in Structure extrahieren

Verfasst: 20.04.2019 10:09
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