Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

festigrat
Posts: 54
Joined: 02 Mar 2017, 06:58

Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

17 Apr 2018, 11:00

Liebe Gemeinschaft,

ich stehe vor folgendem Problem. Ich will Text aus Datei auslesen, die die Dateierweiterung lvt hat (hat xml-Code). Ich habe sie in *.txt umbenannt und kann sie sieht folgendermaßen aus:

<page num="4">
<ref>-99999.0</ref>
<flag>false</flag>
<comment></comment>
<light>100</light>
<error>false</error>
<track num="0">
<text>He! Ho! Waldhüter ihr,
</text>
<text>Schlafhüter mitsammen!</text>
</track>
<track num="1">
<text>He! Ho! Waldhüter ihr,
</text>
<text>Schlafhüter mitsammen!</text>
</track>
<track num="2">
<text>Hey! Ho! Forest sentries indeed!
</text>
<text>More like sleep's sentries! </text>
</track>
</page>
<page num="5">
<ref>-99999.0</ref>
<flag>false</flag>
<comment></comment>
<light>100</light>
<error>false</error>
<track num="0">
<text>So wacht doch mindest am Morgen!</text>
</track>
<track num="1">
<text>So wacht doch mindest am Morgen!</text>
</track>
<track num="2">
<text>At least wake up when it's morning! </text>
</track>
</page>
<page num="6">
<ref>-99999.0</ref>
<flag>false</flag>
<comment></comment>
<light>100</light>
<error>false</error>
<track num="0">
<text></text>
</track>
<track num="1">
<text></text>
</track>
<track num="2">
<text></text>
</track>
</page>


Letztendlich will ich die page num auslesen und den Text dazu. Der deutsche Text ist in der Datei immer doppelt und ich brauche ihn nur einmal. Manchmal gibt es auch drei Zeilen. Ein einziges </text> ist ein Zeilenumbruch.

So soll es letztendlich aussehen:

4, He! Ho! Waldhüter ihr,Schlafhüter mitsammen!,(hier die dritte Zeile, die gerade nicht da ist. Ist sie leer, sollen zwei Kommas folgen),Hey! Ho! Forest sentries indeed!,More like sleep's sentries!,(dritte englische Zeile)
5, usw.

Wenn jemand eine Idee hat, wie ich mit Autohotkey dies auslesen kann, wäre ich sehr dankbar. Viele Grüße!
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

18 Apr 2018, 02:56

Moin,

soll heißen:
  • Es gibt zu jedem <page num> Eintrag immer 3 <track num> Einträge.
  • Die <track num> Einträge 0 und 1 sind immer identisch, deshalb brauchst Du nur die 1 und die 2.
  • Jeder <track num> Eintrag enthält maximal 3 <text> Einträge.
  • Die sollen ausgelesen und mit Kommas getrennt werden. Für leere und fehlende Einträge ist ein Komma zu setzen.
Können Kommas auch innerhalb der Texte vorkommen?
festigrat
Posts: 54
Joined: 02 Mar 2017, 06:58

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

19 Apr 2018, 02:55

Moin,
vielen Dank für Deine Antwort.
Der Text steht ja immer zwischen <text> und </text>. Mir ist nicht klar, mit welchem AHK-Befehl ich das auslesen kann. Diese XML-Datei bereitet mir auch Schwierigkeiten. Wenn ich sie nämlich einfach als Textdatei umbenenne sind dort keine Zeilenumbrüche und sieht so aus:
<page num="4"><ref>-99999.0</ref><flag>false</flag><comment></comment><light>100</light><error>false</error><track num="0"><text>He! Ho! Waldhüter ihr,</text><text>Schlafhüter mitsammen!</text></track><track num="1"><text>He! Ho! Waldhüter ihr,</text><text>Schlafhüter mitsammen!</text></track><track num="2"><text>Hey! Ho! Forest sentries indeed!</text><text>More like sleep's sentries! </text></track></page><page num="5"><ref>-99999.0</ref>

Kopiere ich diesen Text in eine andere Textdatei, sieht es weiterhin so aus, füge ich ihn allerdings hier im Forum ein, sind die Zeilenumbrüche da. Wenn ich bestimmte Ausdrücke durch StrReplace löschen will, geht dies nicht unbedingt, da irgend eine versteckte Formatierung zwischen den Ausdrücken ist. Kann man mit AHK direkt mit XML umgehen?
Dir originale Datei hat die Erweiterung LVT. Ich habe sie einmal angehängt:
Parsifal_de-en.zip
(51.46 KiB) Downloaded 53 times
Ja, Kommas können auch im Text vorkommen. Deswegen ist es doch nicht sinnvoll, den Text einer <page num> mit Kommas zu trennen. Dieser Part ist erst einmal nicht so wichtig. Das kann ich bestimmt noch später klären, jedenfalls muss ich es erst einmal auslesen können.

Vielen Dank schon einmal für Deine Hilfe.
festigrat
Posts: 54
Joined: 02 Mar 2017, 06:58

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

19 Apr 2018, 03:19

Ich habe inzwischen gesehen, dass ich den Text auch als Textdatei exportieren kann, die wahrscheinlich ebenfalls Zeilenumbrüche hat. Öffne ich die Textdatei, sieht der Text folgendermaßen aus: He! Ho! Waldhüter ihr,Schlafhüter mitsammen!. Kopiere ich ihn hier ins Forum erscheint er folgendermaßen:
He! Ho! Waldhüter ihr,
Schlafhüter mitsammen!

So sieht die Textdatei aus:

Code: Select all

------------- NAOTEK export file -------------

Nom: Parsifal_de-en
Auteur: 
Version: 
Pour: 

Piste: DCH de

*************************************************
-99999
*************************************************
-99999
*************************************************
-99999
*************************************************
-99999
*************************************************
-99999
He! Ho! Waldhüter ihr,
Schlafhüter mitsammen!
*************************************************
-99999
So wacht doch mindest am Morgen!
*************************************************
-99999
*************************************************
-99999
Hört ihr den Ruf?
*************************************************
-99999
Nun danket Gott,
dass ihr berufen, ihn zu hören!
*************************************************
-99999
*************************************************
-99999
Jetzt auf, ihr Knaben!
Seht nach dem Bad.
*************************************************
-99999
Zeit ist's, des Königs dort zu harren.   
*************************************************
-99999
Dem Siechbett, das ihn trägt,
voraus seh' ich die Boten schon uns nah'n!
*************************************************
-99999
Heil euch! Wie geht's Amfortas heut?
*************************************************
-99999
Wohl früh verlangt' er nach dem Bade.
*************************************************
Eigentlich ist es ja ganz einfach, nach -99999 soll er auslesen bis *************************************************. Vielleicht liest er ja dann auch die Zeilenumbrüche mit. Aber mit welchem AHK-Befehl mache ich das?
folgt -99999 und ************************************************* ohne Text dazwischen, handelt es sich um einen leeren Titel, was ebenfalls irgendwie gespeichert werden muss.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

19 Apr 2018, 05:39

Ich würde diesen Fall mit dem AHK Befehl StrSplit erledigen.
StrSplit trennt eine Zeichenkette an bestimmten Stellen auf und schreibt die einzelnen Ergebnisse getrennt voneinander auf.
Es gibt 2 Versionen:
StringSplit ist ein Command und die ältere Version - es schreibt die einzelnen Ergebnisse in ein sogenanntes Pseudo-Array bei dem jedes Ergebnis in eine einzelne Variable geschrieben wird.
Zudem wird die Anzahl der unterschiedlichen Ergebnisse in eine eigene Variable gespeichert.
StrSplit ist eine Funktion und die neuere und empfohlene Version - es schreibt alle Ergebnisse in ein Array welches die Funktion zurückgibt.
Über bestimmte Funktionen ( im Falle von Arrays( Objekten ) nennt man Funktionen normalerweiser Methoden ) kann man dann auf verschiedene Eigenschaften des Arrays zugreifen.

Ich würde dir StrSplit empfehlen, da die Logik an sich eigentlich einfacher ist. Pseudo Arrays mögen am Anfang logischer klingen weil man Variablen gewöhnt ist - aber sie sind eigentlich nur umständlich.

In deinem Fall:

Code: Select all

GoSub, defineText ;schreibe den Inhalt deiner Datei in die variable text.
resultat := StrSplit( text, "*************************************************`n-99999" ) ;den Text an der Zeichenkette  *************************************************`n-99999 aufteilen ( `n steht für neue Zeile )
Msgbox % resultat.1 ;den ersten Teil zurückgeben


defineText:
text :=
(
"------------- NAOTEK export file -------------

Nom: Parsifal_de-en
Auteur: 
Version: 
Pour: 

Piste: DCH de

*************************************************
-99999
*************************************************
-99999
*************************************************
-99999
*************************************************
-99999
*************************************************
-99999
He! Ho! Waldhüter ihr,
Schlafhüter mitsammen!
*************************************************
-99999
So wacht doch mindest am Morgen!
*************************************************
-99999
*************************************************
-99999
Hört ihr den Ruf?
*************************************************
-99999
Nun danket Gott,
dass ihr berufen, ihn zu hören!
*************************************************
-99999
*************************************************
-99999
Jetzt auf, ihr Knaben!
Seht nach dem Bad.
*************************************************
-99999
Zeit ist's, des Königs dort zu harren.   
*************************************************
-99999
Dem Siechbett, das ihn trägt,
voraus seh' ich die Boten schon uns nah'n!
*************************************************
-99999
Heil euch! Wie geht's Amfortas heut?
*************************************************
-99999
Wohl früh verlangt' er nach dem Bade.
*************************************************"
)
return
Recommends AHK Studio
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

19 Apr 2018, 05:45

Moin,

Deine lvt Datei ist ein wenig merkwürdig. Mein Hexeditor sagt mir, sie habe das Format UTF-8 ohne BOM. Außerdem findet sich nach der ersten Zeile ein Windows konformer Zeilenumbruch CRLF - 0x0D0A - `r`n. Innerhalb der Datei finden sich aber auch einzelne LF - 0x0A - `n Zeichen. Das bringt zumindest den Windows Editor durcheinander.

Zu Deiner Textdatei: Das Einlesen ist unkompliziert. Ich sehe im Beispiel aber keine englischen Texte. Wo verbergen sich die? Und wie soll das Ergebnis aussehen?
User avatar
Ragnar
Posts: 611
Joined: 30 Sep 2013, 15:25

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

19 Apr 2018, 05:51

Um XML-Dateien auszulesen, empfehle ich Dir das COM-Objekt "MSXML2.DOMDocument.6.0". Zum Beispiel:

Code: Select all

xml := ComObjCreate("MSXML2.DOMDocument.6.0")
xml.async := false
xml.load("Parsifal_de-en.lvt")
MsgBox % xml.selectSingleNode("/book/name").text
Die einzige Voraussetzung ist mindestens Windows XP SP3. Mehr Infos, einschließlich der XPath-Schreibweise, findest Du unter https://autohotkey.com/board/topic/5698 ... ntry367838.
festigrat
Posts: 54
Joined: 02 Mar 2017, 06:58

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

19 Apr 2018, 11:19

Hi, vielen Dank für Eure Ideen. Mit StrSplit bekomme ich tatsächlich auf einfache Weise die gesuchten Zeilen. Dass StrSplit die Daten gleich in ein Array schreibt, war mir gar nicht bekannt. Es ist ja sehr praktisch und damit komme ich auf jeden Fall weiter!
Ich kann mit dem Titel-Programm auch eine Textdatei exportieren, dann allerdings jeweils nur eine Sprache. Deswegen ist englisch nicht dabei. Beide Sprachen sind nur in der lvt-Datei.
Ragnars Variante wäre deshalb für mich sehr vorteilhaft, da die lvt-Datei sowieso vorliegt und ich nicht noch exportieren muss, was die Sache etwas verinfacht. Ich habe es allerdings mit dem Code noch nicht geschafft, einen Text zu extrahieren. Was würde ich denn anstatt /book/name schreiben, um an die erste Zeile zu gelangen?
Am Ende brauche ich z.B. eine csv- oder ini-Datei. Es muss beim Auslesen ersichtlich sein, was, welche Sprache ist und ob es 1, 2 oder 3 Zeilen sind.
z.B:
1;He! Ho! Waldhüter ihr,;Schlafhüter mitsammen!;Zeile 3 deutsch(ansonsten eine leeres Kästchen; Hey! Ho! Forest sentries indeed!;More like sleep's sentries!;Zeile 3 englisch

Bei He! Ho! fängt es ja an. Alles, was davor ist, kann weggelassen werden. In der Textdatei ist es für mich sehr einfach, vorne alles wegzulöschen.

Nochmals vielen Dank für Eure Hilfe. Ich bin dadurch sehr viel weitergekommen!
User avatar
Ragnar
Posts: 611
Joined: 30 Sep 2013, 15:25

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

19 Apr 2018, 12:43

Code: Select all

SetBatchLines -1
xml := ComObjCreate("MSXML2.DOMDocument.6.0")
xml.async := false
xml.load("Parsifal_de-en.lvt")
pages := xml.selectSingleNode("/book/container/container/container").childNodes
Liste := FileOpen("Liste.txt", "w`n")
Startnummer := 4
Loop % pages.length
{
    if (A_Index <= Startnummer)
        continue
    n := A_Index - Startnummer 
    DE1 := pages.item(A_Index).selectSingleNode("track[1]/text[1]").text
    DE2 := pages.item(A_Index).selectSingleNode("track[1]/text[2]").text
    DE3 := pages.item(A_Index).selectSingleNode("track[1]/text[3]").text
    EN1 := pages.item(A_Index).selectSingleNode("track[3]/text[1]").text
    EN2 := pages.item(A_Index).selectSingleNode("track[3]/text[2]").text
    EN3 := pages.item(A_Index).selectSingleNode("track[3]/text[3]").text
    Liste.WriteLine(n "|" DE1 "|" DE2 "|" DE3 "|" EN1 "|" EN2 "|" EN3)
}
Als Trennzeichen wäre z. B. "|" sinnvoller, weil manche Sätze ein Semikolon enthalten.
festigrat
Posts: 54
Joined: 02 Mar 2017, 06:58

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

19 Apr 2018, 15:08

Hallo Ragnar,

wow, das Skript habe ich eingebaut und es scheint perfekt zu funktionieren! Ich muss es morgen noch ausgiebig testen. Die anderen Trennzeichen sind sehr sinnvoll!!!
Wenn der Text nun mit einer anderen Startnummer beginnt, könnte ich diese ja wahrscheinlich einfach ändern (Zeile 7), oder? Ich weiß noch nicht sicher, ob es immer mit Seite 4 losgeht. Vielleicht muss ich mir noch ein Skript schreiben, welches eine Page nach der anderen anzeigt und sobald ich den ersten relevanten Titel sehe, ich diesen auswähle und dieser meine Startnummer ist.
Also, herzlichen Dank. Diese Lösung ist super genial!!! :-)
User avatar
Ragnar
Posts: 611
Joined: 30 Sep 2013, 15:25

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

19 Apr 2018, 15:24

Kein Problem :thumbup:
festigrat wrote:Wenn der Text nun mit einer anderen Startnummer beginnt, könnte ich diese ja wahrscheinlich einfach ändern (Zeile 7), oder?
Ja, genau dafür ist diese Variable vorgesehen.
festigrat
Posts: 54
Joined: 02 Mar 2017, 06:58

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

19 Apr 2018, 15:32

Alles klar, ich teste es mal morgen ausgiebig!
festigrat
Posts: 54
Joined: 02 Mar 2017, 06:58

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

20 Apr 2018, 01:55

So, durch Eure Hilfe ist der erste Teil des Skriptes fertig. Ich lasse das Skript zuerst die Liste schreiben und gehe dann mit einer MsgBox Zeile für Zeile durch. Sobald die erste richtige Zeile da ist, klicke ich in der MsgBox auf Yes und dann wird nochmal die Liste geschrieben, nun mit dem richtigen Anfang. In der letzten Zeile habe ich ein # zu den Trennstrichen | geschrieben. Ich lese die Kästchen folgendermaßen aus:

Code: Select all

StringSplit, word_array, GanzeZeile, `|, .
Wenn ich dies tue, sind aus irgendeinem Grund die Punkte weg, Ausrufezeichen und Fragezeichen jedoch nicht. # lösche ich dann mit SubStr()
Man hätte das mit Sicherheit noch etwas eleganter lösen können, aber da ich im Gegensatz zu Euch kein Profi bin, kann ich damit gut leben. Jetzt habe ich nur noch ein Problem mit dem Subrahieren von Zeiten. Ich hatte dies im falschen Forum gepostet und hoffe dennoch, hier eine Antwort zu bekommen. Vielleicht habt Ihr ja sogar Interesse. Nochmal vielen Dank für Euen Einsatz. Hier der abschließende Code:

Code: Select all

FileSelectFolder, Folder
FileSelectFile, SelectedFile, 3, , Open a file, Text Documents (*.lvt)
SetWorkingDir %Folder%

SetBatchLines -1
xml := ComObjCreate("MSXML2.DOMDocument.6.0")
xml.async := false
xml.load(SelectedFile)
pages := xml.selectSingleNode("/book/container/container/container").childNodes
Liste := FileOpen("Liste.txt", "w`n")
Startnummer := 0
Loop % pages.length
{
    if (A_Index <= Startnummer)
        continue
    n := A_Index - Startnummer 
    DE1 := pages.item(A_Index).selectSingleNode("track[1]/text[1]").text
    DE2 := pages.item(A_Index).selectSingleNode("track[1]/text[2]").text
    DE3 := pages.item(A_Index).selectSingleNode("track[1]/text[3]").text
    EN1 := pages.item(A_Index).selectSingleNode("track[3]/text[1]").text
    EN2 := pages.item(A_Index).selectSingleNode("track[3]/text[2]").text
    EN3 := pages.item(A_Index).selectSingleNode("track[3]/text[3]").text
    Liste.WriteLine(n "|" DE1 "#|" DE2 "#|" DE3 "#|" EN1 "#|" EN2 "#|" EN3 "#")
}

seite :=1
Loop
{
    FileReadLine, OutputVar, Liste.txt, %seite%
    MsgBox, 4, erste Zeile finden, %OutputVar%
    IfMsgBox, yes
    {
        goto break_outer3
    }
    IfMsgBox, no
    {
        z=%seite%
        seite :=z+1
    }
    
}

break_outer3:
z=%seite%
seite :=z-1

SetBatchLines -1
xml := ComObjCreate("MSXML2.DOMDocument.6.0")
xml.async := false
xml.load(SelectedFile)
pages := xml.selectSingleNode("/book/container/container/container").childNodes
Liste := FileOpen("Liste.txt", "w`n")
Startnummer := seite
Loop % pages.length
{
    if (A_Index <= Startnummer)
        continue
    n := A_Index - Startnummer 
    DE1 := pages.item(A_Index).selectSingleNode("track[1]/text[1]").text
    DE2 := pages.item(A_Index).selectSingleNode("track[1]/text[2]").text
    DE3 := pages.item(A_Index).selectSingleNode("track[1]/text[3]").text
    EN1 := pages.item(A_Index).selectSingleNode("track[3]/text[1]").text
    EN2 := pages.item(A_Index).selectSingleNode("track[3]/text[2]").text
    EN3 := pages.item(A_Index).selectSingleNode("track[3]/text[3]").text
    Liste.WriteLine(n "|" DE1 "#|" DE2 "#|" DE3 "#|" EN1 "#|" EN2 "#|" EN3 "#")
}
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

20 Apr 2018, 03:08

Moin,

es scheint mir nicht besonders 'elegant', die XML-Datei zweimal auszuwerten und zu schreiben.

Deine Beispieldatei enthält eine interessante Struktur:

Code: Select all

<trackconfiguration>
   <track num="0">
      <name>Übertitel Saal</name>
      <fontfamily>Verdana</fontfamily>
      <fontsize>44</fontsize>
      <foreground>-1</foreground>
      <bold>false</bold>
      <italic>false</italic>
      <underline>false</underline>
      <left>false</left>
      <center>true</center>
      <right>false</right>
      <effect>9</effect>
      <vitesseArrivee>5</vitesseArrivee>
      <vitesseDepart>5</vitesseDepart>
      <retard>0</retard>
   </track>
   <track num="1">
      <name>DCH de</name>
      <fontfamily>Verdana</fontfamily>
      <fontsize>20</fontsize>
      <foreground>-1</foreground>
      <bold>false</bold>
      <italic>false</italic>
      <underline>false</underline>
      <left>true</left>
      <center>false</center>
      <right>false</right>
      <effect>0</effect>
      <vitesseArrivee>5</vitesseArrivee>
      <vitesseDepart>5</vitesseDepart>
      <retard>0</retard>
   </track>
   <track num="2">
      <name>DCH en</name>
      <fontfamily>Verdana</fontfamily>
      <fontsize>20</fontsize>
      <foreground>-1</foreground>
      <bold>false</bold>
      <italic>true</italic>
      <underline>false</underline>
      <left>false</left>
      <center>false</center>
      <right>true</right>
      <effect>0</effect>
      <vitesseArrivee>5</vitesseArrivee>
      <vitesseDepart>5</vitesseDepart>
      <retard>0</retard>
   </track>
</trackconfiguration>
Das könnte bedeuten:
  • Die Tracknummer 0 ist für einen speziellen Zweck reserviert: <name>Übertitel Saal</name>
  • Die Tracknummer 1 enthält die erste Sprachversion: <name>DCH de</name>
  • Die Tracknummer 2 enthält die zweite Sprachversion: <name>DCH en</name>
Es könnte also reichen, am Anfang die Seiten zu überspringen, die weder in Track1 noch in Track2 Text enthalten.

Auch diese Schachtelung ist interessant:

Code: Select all

<container type="Main">
   <name>Parsifal_de-en</name>
   <container type="Acte">
      <name>Akt 1</name>
      <container type="Scene">
         <name>Szene 1</name>
Das könnte bedeuten, dass eine .lvt Datei auch mehrere Acte Container mit mehreren untergeordneten Scene Containern enthalten kann. Dann würde der Suchpfad

Code: Select all

xml.selectSingleNode("/book/container/container/container").childNodes
nur die erste Szene des ersten Akts auslesen.
festigrat
Posts: 54
Joined: 02 Mar 2017, 06:58

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

20 Apr 2018, 15:08

Hi just me,
natürlich ist es nicht elegant, aber da ich in meinen Fähigkeiten sehr limitiert bin, war dies eine Möglichkeit für mich.
Und Du hast richtig getippt, denn die Tracknummer 0 könnte man ganz weglassen und nur Tracknummer 1 und 2 auslesen. Dann würde man sich das Auswählen des Anfangs sparen.
Die verschiedenen Akte auszulesen, wäre zwar ein nettes Feature, aber es kommt so selten vor, dass man kaum von einem Mehraufwand sprechen kann, wenn man meine Ausgabedatei dann an dieser Stelle zersägt.
Hast Du eine Idee, wie man mit Ragnars Skript diese Tracknummer 0 am Anfang weglässt? Wenn nicht, ist es auch nicht so schlimm. Ich brauche das Skript nicht sehr oft und dann kann ich auch diese drei Klicks mehr verkraften.

Vielen Dank für Deine Anmerkungen!
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

21 Apr 2018, 03:51

Moin,

natürlich habe ich eine Idee. Bevor ich aber etwas mache, würde ich gern wissen, wie Du die Ausgabedatei weiter verarbeitest. Der Inhalt einer Datei sollte ja möglichst dieser weiteren Verarbeitung entsprechen.

'Notlösungen' wie
... aber es kommt so selten vor, dass man kaum von einem Mehraufwand sprechen kann, wenn man meine Ausgabedatei dann an dieser Stelle zersägt.
sollte man nur nutzen, wenn im Skript überhaupt ein nennenswerter Mehraufwand entsteht. Und gerade wenn es "so selten vorkommt", erhöht sich das Risiko, dass man es nicht bemerkt. Außerdem müsste man in diesem Fall die Eingabedatei (.lvt) 'zersägen'. Welche Auswirkungen hätte es auf die Weiterverarbeitung, wenn die Ausgabedatei mehrere Akte enthält?
festigrat
Posts: 54
Joined: 02 Mar 2017, 06:58

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

23 Apr 2018, 04:23

Moin,

danke, dass Du Dich hier so ins Zeug legst! Ich will alle Titel der lvt-Datei in einem Videoprogramm als Untertitel einbinden. Während der Versanstaltung wird ein Übertitel nach dem anderen im Saal gezeigt und ich logge per AHK-Skript mit, wann dies passiert. Dann ziehe ich die Zeiten voneinander ab, damit der erste Untertitel bei 00:00:00,000 startet. Dann verknüpfe ich die Zeiten meiner Log-Datei mit den einzelnen Titeln der lvt-Datei, und zwar für deutsch und englisch getrennt. Manchmal ist auch nur eine Sprache da, aber dafür habe ich zur Zeit keine Beispieldatei. Danach schreibe ich einen einzelen langen Titel für mein Videoprogramm in folgenden Format:

Code: Select all

1
00:00:00,000 --> 00:00:03,960
Zeile1
Zeile2

2
00:00:04,120 --> 00:00:08,160
Zeile4
Zeile 5

3
00:00:08,320 --> 00:00:12,560
Das geht mit FileAppend ja sehr einfach. In meinem Videoprogramm habe ich dann ein eiziges Titel-Clip, welches den Text innerhalb des Clips wechselt. Ist eine Oper 3 Stunden lang, ziehe ich dieses Clip einfach drei Stunden lang auf und zertrenne es manuell nach den Akten. Dies ist sehr einfach. Wenn ich die lvt-Datei pro Akt auslese, muss ich auch wieder den Timecode des ersten Titels des zweiten und dritten Aktes auf 00:00:00,000 zurücksetzen. Das würde ich mir durch einen langen Titel ersparen.
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

23 Apr 2018, 04:37

Moin,

ich bin schon etwas älter und begreife deshalb wohl nicht mehr alles ohne detaillierte Erklärung. Was ich brauche, um das Ganze zu verstehen, ist Folgendes:

Welche Felder aus den Zeilen der Ausgabedatei werden wie und wofür genutzt (am Besten mit einer Beipielzeile und Deinem Code)?

Könntest Du in Bezug auf mehrere Akte bzw. mehrere Scenen pro Akt noch weitere Informationen in der Ausgabedatei brauchen? Wenn ja, welche und wohin sollen die geschrieben werden?
User avatar
LuckyJoe
Posts: 335
Joined: 02 Oct 2013, 09:52

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

23 Apr 2018, 13:29

Hi,

ich hoffe, niemand ist mir böse, wenn ich auf Tools aufmerksam mache, die das Erstellen und Editieren von Untertiteln zu Videos recht einfach ermöglichen, wie z.B.:
Shotcut https://shotcut.org/download/ oder Subtitle Edit http://www.nikse.dk/. Beide Programme sind kostenlos und in der Bedienung wohl ganz simpel (mit Shotcut habe ich schon selber gearbeitet).
Vielleicht braucht man das Rad ja gar nicht neu zu erfinden?

Ansonsten: Viel Erfolg und herzliche Grüße
Lucky Joe
Herzliche Grüße aus dem Rheinland
Lucky Joe
festigrat
Posts: 54
Joined: 02 Mar 2017, 06:58

Re: Auslesen bestimmter Wörter aus einer html-ähnlichen Datei

25 Apr 2018, 09:07

Hallo,
ich habe das Skript nun fertig gestellt und ich denke, es funktioniert bestens. Folgendes läuft ab. Eine Veranstaltung mit Sprache wird gefilmt. Gleichzeitig wird im Saal der Text eingeblendet, indem jemand den Text mitliest und bei der nächsten Zeile auf "Weiter" drückt. Dies sind die Übertitel der lvt-Datei. Des Weiteren befinden sich dann die Sprache1 und Sprache2 in der lvt-Datei, in der Beispieldatei deutsch und englisch.
Ich lese nun die lvt-Datei aus und logge mit, wann derjenige, der die Titel im Saal wechselt, dies tut. Den Zeitpunkt des ersten relevanten Übertitels im Saal setze ich auf Null und verbinde ihn nun mit den Titeln der lvt-Datei. Damit kann ich eine Untertitel-Datei automatisch erstellen, die dann den gesamten Text beinhaltet und vor allem an der richtigen Stelle den richtigen Text zeigt. Dies kann ich unter das Video legen.

Zu der Frage von just me. Im Prinzipt ist Ragnars Skript funktionstüchtig. Es könnte unter Umständen geschickt sein, einen einzelnen Akt auszulesen, aber ich kann auch einen langen Titel haben und zerschneide ihn dann in die einzelnen Akte. Ist das Prozedere jetzt einigermaßen verständlich?

Das Ausgabeformat ist jeweils eine Liste pro Sprache:
1
00:00:00,000 --> 00:00:03,960
Zeile1 deutsch
(fasls vorhanden) Zeile2 deutsch
(falls vorhanden) Zeile3 deutsch

2
00:00:04,120 --> 00:00:08,160
Zeile4
(falls vorhanden) Zeile 5

Hier ist der Code: Mitschreiben, wann während der Veranstaltung auf weiter oder zurück geklickt wird:

Code: Select all

Var1 =,


~Down::

Var := A_MSec
SetFormat, float, 03.0
Var := Var / 20
Var := Var * 20
Var := Format("{:03}",Var)
if Var contains 1000 
{
	Var :=000
}

 
FileAppend, %A_Hour%:%A_Min%:%A_Sec%%Var1%%Var%;1`n, C:\Autohotkey\Output\%A_YYYY%%A_MM%%A_DD%_UT-Log.csv

return
 
~Up::
 
Var := A_MSec
SetFormat, float, 03.0
Var := Var / 20
Var := Var * 20
Var := Format("{:03}",Var)
if Var contains 1000 
{
	Var :=000
}

FileAppend, %A_Hour%:%A_Min%:%A_Sec%%Var1%%Var%;-1`n, C:\Autohotkey\Output\%A_YYYY%%A_MM%%A_DD%_UT-Log.csv

return
Dann folgt das Auslesen der LVT-Datei, bestimmen der ersten Zeile und das definieren des ersten relevanten Tastenklicks auf Weiter:

Code: Select all

FileSelectFolder, Folder
SetWorkingDir %Folder%
FileSelectFile, SelectedFile, 3, %Folder%, Open a file, Text Documents (*.lvt)
IniWrite, %Folder%, %A_ScriptDir%\Pfad.ini, Pfad, Pfad1


SetBatchLines -1
xml := ComObjCreate("MSXML2.DOMDocument.6.0")
xml.async := false
xml.load(SelectedFile)
pages := xml.selectSingleNode("/book/container/container/container").childNodes
Liste := FileOpen("Liste.txt", "w`n")
Startnummer := 0
Loop % pages.length
{
    if (A_Index <= Startnummer)
        continue
    n := A_Index - Startnummer 
    DE1 := pages.item(A_Index).selectSingleNode("track[1]/text[1]").text
    DE2 := pages.item(A_Index).selectSingleNode("track[1]/text[2]").text
    DE3 := pages.item(A_Index).selectSingleNode("track[1]/text[3]").text
    EN1 := pages.item(A_Index).selectSingleNode("track[3]/text[1]").text
    EN2 := pages.item(A_Index).selectSingleNode("track[3]/text[2]").text
    EN3 := pages.item(A_Index).selectSingleNode("track[3]/text[3]").text
    Liste.WriteLine(n "|" DE1 "#|" DE2 "#|" DE3 "#|" EN1 "#|" EN2 "#|" EN3 "#")
}

seite :=1
Loop
{
    FileReadLine, OutputVar, Liste.txt, %seite%
    if OutputVar contains 1|Bitte schalten Sie Ihr Mobiltelefon ab.#|Vielen Dank.#|#|#|#|#
    {
        goto, NextLine1
    }
    if OutputVar contains 2|#|#|#|#|#|#
    {
        goto, NextLine1
    }
    if OutputVar contains 3|Please turn off your mobile phone.#|Thank you.#|#|#|#|# 
    {
        goto, NextLine1
    }
    if OutputVar contains 4|#|#|#|#|#|#
    {
        goto, NextLine1
    }
      
    
    MsgBox, 4, erste Zeile finden, %OutputVar%
    
    IfMsgBox, yes
    {
        goto break_outer3
    }
    IfMsgBox, no
    {
        goto, NextLine1
   } 
    
    
    NextLine1:
    
        z=%seite%
        seite :=z+1
    
    
}

break_outer3:
z=%seite%
seite :=z-1

SetBatchLines -1
xml := ComObjCreate("MSXML2.DOMDocument.6.0")
xml.async := false
xml.load(SelectedFile)
pages := xml.selectSingleNode("/book/container/container/container").childNodes
Liste := FileOpen("UT-LVT.txt", "w`n")
Startnummer := seite
Loop % pages.length
{
    if (A_Index <= Startnummer)
        continue
    n := A_Index - Startnummer 
    DE1 := pages.item(A_Index).selectSingleNode("track[1]/text[1]").text
    DE2 := pages.item(A_Index).selectSingleNode("track[1]/text[2]").text
    DE3 := pages.item(A_Index).selectSingleNode("track[1]/text[3]").text
    EN1 := pages.item(A_Index).selectSingleNode("track[3]/text[1]").text
    EN2 := pages.item(A_Index).selectSingleNode("track[3]/text[2]").text
    EN3 := pages.item(A_Index).selectSingleNode("track[3]/text[3]").text
    Liste.WriteLine(n "|" DE1 "#|" DE2 "#|" DE3 "#|" EN1 "#|" EN2 "#|" EN3 "#")
}

FileDelete, Liste.txt

FileSelectFile, SelectedFile, 3, %Folder%, Log-Datei öffnen, Text Documents (*.csv)
FileAppend, asdfjklö`n, %SelectedFile%
;FileAppend, `nasdfjklö, 20180423_UT-Log.csv


zeile :=1
Loop
{
    FileReadLine, OutputVar, %SelectedFile%, %zeile%
	;FileReadLine, OutputVar, 20180423_UT-Log.csv, %zeile%
	StringSplit, word_a, Outputvar, `;, .
    MsgBox, 4, ersten Titel finden, %OutputVar%
    IfMsgBox, yes
    {
        goto break_outer4
    }
    IfMsgBox, no
    {
        z=%zeile%
        zeile :=z+1
    }
    
}

break_outer4:

Versatz = %word_a1%

ZeileLVT :=1

Nummer :=1

;FileSelectFile, LVTListe, 3, %Folder%, Untertitel-Liste auswählen, Text Documents (*.txt)

Loop,
{
	
	;FileReadLine, GanzeZeile, 20180423_UT-Log.csv, %zeile%
	
	FileReadLine, GanzeZeile, %SelectedFile%, %zeile%
	StringSplit, word_array, GanzeZeile, `;, .
	
	;FileReadLine, GanzeZeileLVT, %LVTListe%, %ZeileLVT%
	FileReadLine, GanzeZeileLVT, UT-LVT.txt, %ZeileLVT%
	StringSplit, word_arrayLVT, GanzeZeileLVT, `|, .
	word_arrayLVT2 := SubStr(word_arrayLVT2, 1 , -1)
	word_arrayLVT3 := SubStr(word_arrayLVT3, 1 , -1)
	word_arrayLVT4 := SubStr(word_arrayLVT4, 1 , -1)
	word_arrayLVT5 := SubStr(word_arrayLVT5, 1 , -1)
	word_arrayLVT6 := SubStr(word_arrayLVT6, 1 , -1)
	word_arrayLVT7 := SubStr(word_arrayLVT7, 1 , -1)
	
	if word_array1 contains asdfjklö
	{
		goto break_outer5
	}
	


Minuend := ConvertToMilliseconds(word_array1)
Subtrahend := ConvertToMilliseconds(Versatz)
Differenz := Minuend - Subtrahend
;MsgBox % ConvertToHHMMSSMS(Differenz)

ConvertToMilliseconds(HHMMSSMS)
{
    HH := SubStr(HHMMSSMS, 1, 2) * 1000 * 3600
    MM := SubStr(HHMMSSMS, 4, 2) * 1000 * 60
    SS := SubStr(HHMMSSMS, 7, 2) * 1000
    MS := SubStr(HHMMSSMS, 10)
    return HH + MM + SS + MS
}

ConvertToHHMMSSMS(Milliseconds)
{
    HH := Milliseconds // 3600000
    remain := Mod(Milliseconds, 3600000)
    MM := remain // 60000
    remain := Mod(remain, 60000)
    SS := remain // 1000
    remain := Mod(remain, 1000)
    MS := Mod(remain, 1000)
    return Format("{:02}:{:02}:{:02},{:03}", HH, MM, SS, MS)
}
	
	z=%zeile%
	zeile :=z+1
	
	x=%ZeileLVT%
	y=%word_array2%
	
	ZeileLVT :=x+y
	
	
	;FileReadLine, GanzeZeile, 20180423_UT-Log.csv, %zeile%
	FileReadLine, GanzeZeile, %SelectedFile%, %zeile%
	StringSplit, word_array_ende, GanzeZeile, `;, .

Minuend2 := ConvertToMilliseconds2(word_array_ende1)
Subtrahend2 := ConvertToMilliseconds2(Versatz)
Differenz2 := Minuend2 - Subtrahend2


ConvertToMilliseconds2(HHMMSSMS)
{
    HH := SubStr(HHMMSSMS, 1, 2) * 1000 * 3600
    MM := SubStr(HHMMSSMS, 4, 2) * 1000 * 60
    SS := SubStr(HHMMSSMS, 7, 2) * 1000
    MS := SubStr(HHMMSSMS, 10)
    return HH + MM + SS + MS
}

ConvertToHHMMSSMS2(Milliseconds)
{
    HH := Milliseconds // 3600000
    remain := Mod(Milliseconds, 3600000)
    MM := remain // 60000
    remain := Mod(remain, 60000)
    SS := remain // 1000
    remain := Mod(remain, 1000)
    MS := Mod(remain, 1000)
    return Format("{:02}:{:02}:{:02},{:03}", HH, MM, SS, MS)
}
	
	Zahl1 = % ConvertToHHMMSSMS(Differenz)
	Zahl2 = % ConvertToHHMMSSMS2(Differenz2)
    
    if Zahl2 = 00:00:00,000
    {
        Zahl2 = %Zahl1%
    }
	
	FileAppend %Nummer%`n, Sprache1.srt
	FileAppend, %Zahl1% --> %Zahl2%, Sprache1.srt
	FileAppend, `n%word_arrayLVT2%`n, Sprache1.srt
	FileAppend, %word_arrayLVT3%`n, Sprache1.srt
	FileAppend, %word_arrayLVT4%`n, Sprache1.srt
	
	FileAppend %Nummer%`n, Sprache2.srt
	FileAppend, %Zahl1% --> %Zahl2%, Sprache2.srt
	FileAppend, `n%word_arrayLVT5%`n, Sprache2.srt
	FileAppend, %word_arrayLVT6%`n, Sprache2.srt
	FileAppend, %word_arrayLVT7%`n, Sprache2.srt
	
	n=%Nummer%
	Nummer :=n+1
		
}

break_outer5:
MsgBox, Fertig!
ExitApp

Return to “Ich brauche Hilfe”

Who is online

Users browsing this forum: gero, Rohwedder and 39 guests