Ergebnis 1 bis 19 von 19

Thema: Hilfe - Datenbereinigung/Validierungswerkzeug

  1. #1

    Hilfe - Datenbereinigung/Validierungswerkzeug

    Hallo,

    ein Hilfegesuch. Konkret geht es darum, Inhalte einer Quelldatei mit der Ausgabe einer anderen Software abzugleichen und gefundene Inhalte zu entfernen, so dass nur übrig bleibt was nicht erkannt wurde. Ich habe aktuell einen Versuch mit und ohne Regex, in Python - es ist allerdings nicht auf Python eingeschränkt, sondern es kann jede andere Sprache sein. Es gibt allerdings Fehler, heißt das in Python zu früh ersetzt wird str.replace oder der Regex nicht greift.
    Das äußert sich so, das Daten übrig bleiben oder zu früh greifen beim Ersetzen/Strippen:

    Beispiel "xt" ist gesucht:
    "Text xtz" entfernt fälschlicherweise zu diesem: "Te xtz"

    Aktuell gibt es ein Python Skript ("datachecker.py") - welches Regex verwendet, mehr oder weniger optimal und nicht fehlerfrei.
    Ein zweites Skript hänge ich hier an "datachecker2.py", mit dem ich aktuell versuche zu filtern, aber es greift nicht wie gedacht, vermutlich ein Logikfehler?
    Hier das aktuelle "datachecker2.py" Skript, ohne Regex, nicht auf Github da zum testen: datachecker2.py.rar

    Background:
    Es geht um die Ausgabe von folgendem Projekt: https://github.com/jrie/wicked (C) - unter Verwendung der folgenden Quelldatei.
    Die Quelldatei, nicht auf Github zu hosten weil 221 MB, gepackt, groß - daher der Download vom Webspace: https://dwrox.net/enwiki-20160720-pa...0030303.tar.gz

    Zur Quelldatei, es handelt sich um einen Wikipedia Dump (.xml). Diese muß in "data" entpackt werden.


    Die Ausgabe erfolgt geordnet, aber in mehrere Dateien (*.txt) :
    - xmltags
    - xmldata
    - words
    - wikitags
    - enitites

    Code (C):
    1. #define DICTIONARYFILE "words.txt"
    2. #define WIKITAGSFILE "wikitags.txt"
    3. #define XMLTAGFILE "xmltags.txt"
    4. #define XMLDATAFILE "xmldata.txt"
    5. #define ENTITIESFILE "entities.txt"
    ... mit Parametern wie "Position in der Zeile", "Zeilenummer" des Elements, Formatierung ja/nein, Wiki Tag Typ, Spaces.
    Eine genau Auflistung einer Zeile in den Textdateien/Outputs - mit Variablennamen und Speicherfunktion.

    Word, Entity + WikiTag + XML und XML Datendaten:
    Code (C):
    1. bool writeOutDataFiles(const struct parserBaseStore* parserRunTimeData, struct xmlDataCollection* xmlCollection) {
    2.   struct xmlNode *xmlTag = NULL;
    3.   struct wikiTag *wTag = NULL;
    4.   struct word* wordElement = NULL;
    5.   struct entity* entityElement = NULL;
    6.  
    7.   for (unsigned int i = 0; i < xmlCollection->count; ++i) {
    8.     xmlTag = &xmlCollection->nodes[i];
    9.     fprintf(parserRunTimeData->xmltagFile, "%d|%d|%d|%d|%s\n", xmlTag->start , xmlTag->end, xmlTag->isClosed, xmlTag->isDataNode, xmlTag->name);
    10.  
    11.     for (unsigned int j = 0; j < xmlTag->keyValuePairs; ++j) {
    12.       fprintf(parserRunTimeData->xmldataFile, "%d|%d|%s|%s\n", xmlTag->start, xmlTag->end, xmlTag->keyValues[j].key, xmlTag->keyValues[j].value);
    13.     }
    14.  
    15.     for (unsigned int j = 0; j < xmlTag->wTagCount; ++j) {
    16.       wTag = &xmlTag->wikiTags[j];
    17.       writeOutTagData(parserRunTimeData, wTag);
    18.     }
    19.  
    20.     for (unsigned int j = 0; j < xmlTag->wordCount; ++j) {
    21.       wordElement = &xmlTag->words[j];
    22.       fprintf(parserRunTimeData->dictFile, "%u|%u|%u|%d|%d|%ld|%d|%d|%d|%d|0|%s\n", wordElement->position, wordElement->lineNum, wordElement->readerPos, wordElement->preSpacesCount, wordElement->spacesCount, strlen(wordElement->data), wordElement->dataFormatType, wordElement->ownFormatType, wordElement->formatStart, wordElement->formatEnd, wordElement->data);
    23.     }
    24.  
    25.  
    26.     for (unsigned int j = 0; j < xmlTag->entityCount; ++j) {
    27.       entityElement = &xmlTag->entities[j];
    28.       fprintf(parserRunTimeData->entitiesFile, "%u|%u|%u|%d|%d|%d|%d|%d|%d|%s\n",  entityElement->position, entityElement->lineNum, entityElement->readerPos, entityElement->preSpacesCount, entityElement->spacesCount, entityElement->dataFormatType, entityElement->ownFormatType, entityElement->formatStart, entityElement->formatEnd, entityElement->data);
    29.     }
    30.   }
    31.  
    32.   return true;
    33. }

    Word + Entity + WikiTag in einem WikiTag:

    Code (C):
    1. bool writeOutTagData(const struct parserBaseStore* parserRunTimeData, wikiTag *wTag) {
    2.   struct word* wordElement = NULL;
    3.   struct entity* entityElement = NULL;
    4.   struct wikiTag* wikiTagElement = NULL;
    5.  
    6.   fprintf(parserRunTimeData->wtagFile, "%u|%u|%u|%d|%d|%d|%d|%d|%d|%d|%u|%ld|%s\n",  wTag->position, wTag->lineNum, wTag->readerPos, wTag->preSpacesCount, wTag->spacesCount, wTag->tagType, wTag->dataFormatType, wTag->ownFormatType, wTag->formatStart, wTag->formatEnd, wTag->tagLength, strlen(wTag->target), wTag->target);
    7.  
    8.   for (unsigned int k = 0; k < wTag->wordCount; ++k) {
    9.     wordElement = &wTag->pipedWords[k];
    10.     fprintf(parserRunTimeData->dictFile, "%u|%u|%u|%d|%d|%ld|%d|%d|%d|%d|1|%s\n", wordElement->position, wordElement->lineNum, wordElement->readerPos, wordElement->preSpacesCount, wordElement->spacesCount, strlen(wordElement->data), wordElement->dataFormatType, wordElement->ownFormatType, wordElement->formatStart, wordElement->formatEnd, wordElement->data);
    11.   }
    12.  
    13.   for (unsigned int k = 0; k < wTag->wTagCount; ++k) {
    14.     wikiTagElement = &wTag->pipedTags[k];
    15.     writeOutTagData(parserRunTimeData, wikiTagElement);
    16.   }
    17.  
    18.   for (unsigned int k = 0;k < wTag->entityCount; ++k) {
    19.     entityElement = &wTag->pipedEntities[k];
    20.     fprintf(parserRunTimeData->entitiesFile, "%u|%u|%u|%d|%d|%d|%d|%d|%d|%s\n",  entityElement->position, entityElement->lineNum, entityElement->readerPos, entityElement->preSpacesCount, entityElement->spacesCount, entityElement->dataFormatType, entityElement->ownFormatType, entityElement->formatStart, entityElement->formatEnd, entityElement->data);
    21.   }
    22. }
    Für Fragen zum Format oder den Werten, einfach rein hierher, falls nicht ersichtlich.
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ dwrox.net

  2. #2
    Bot #0384479 Avatar von BurnerR
    Registriert seit
    Jul 2013
    Beiträge
    3.956
    ngb:news Artikel
    1

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    Kannst du konkreter beschreiben, was du machen möchtest?
    Am besten mit Minimalbeispiel vorher/nachher.

  3. #3
    1998

    Veteran

    (Threadstarter)

    Avatar von theSplit
    Registriert seit
    Aug 2014
    Beiträge
    4.709
    ngb:news Artikel
    1

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    Gegeben ist der Wikipedia Dump, der sieht wie folgt aus (XML Snippet) und die Ausgabedaten von Wicked - Wertet die XML aus und schreibt die Daten in die Datendateien, also Wörter nach 'words.txt', XML nach 'xmltags,txt' und 'xmldata.txt', Entities nach 'entities.txt'.

    Hier ein zufälliger Auszug aus < 100 Zeilen der Wikipedia XML:

    Code (XML):
    1.       <contributor>
    2.         <username>Eduen</username>
    3.         <id>7527773</id>
    4.       </contributor>
    5.       <comment>this was redundant</comment>
    6.       <model>wikitext</model>
    7.       <format>text/x-wiki</format>
    8.       <text xml:space="preserve">{{Redirect2|Anarchist|Anarchists|the fictional character|Anarchist (comics)|other uses|Anarchists (disambiguation)}}
    9. {{pp-move-indef}}
    10. {{Use British English|date=January 2014}}
    11. {{Anarchism sidebar}}
    12. {{Basic forms of government}}
    13.  
    14. '''Anarchism''' is a [[political philosophy]] that advocates [[self-governance|self-governed]] societies based on voluntary institutions. These are often described as [[stateless society|stateless societies]],&lt;ref&gt;&quot;ANARCHISM, a social philosophy that rejects authoritarian government and maintains that voluntary institutions are best suited to express man's natural social tendencies.&quot; George Woodcock. &quot;Anarchism&quot; at The Encyclopedia of Philosophy&lt;/ref&gt;&lt;ref&gt;&quot;In a society developed on these lines, the voluntary associations which already now begin to cover all the fields of human activity would take a still greater extension so as to substitute themselves for the state in all its functions.&quot; [http://www.theanarchistlibrary.org/HTML/Petr_Kropotkin___Anarchism__from_the_Encyclopaedia_Britannica.html Peter Kropotkin. &quot;Anarchism&quot; from the Encyclopædia Britannica]&lt;/ref&gt;&lt;ref&gt;&quot;Anarchism.&quot; The Shorter Routledge Encyclopedia of Philosophy. 2005. p. 14 &quot;Anarchism is the view that a society without the state, or government, is both possible and desirable.&quot;&lt;/ref&gt;&lt;ref&gt;Sheehan, Sean. Anarchism, London: Reaktion Books Ltd., 2004. p. 85&lt;/ref&gt; although several authors have defined them more specifically as institutions based on non-[[Hierarchy|hierarchical]] [[Free association (communism and anarchism)|free associations]].&lt;ref&gt;&quot;as many anarchists have stressed, it is not government as such that they find objectionable, but the hierarchical forms of government associated with the nation state.&quot; Judith Suissa. ''Anarchism and Education: a Philosophical Perspective''. Routledge. New York. 2006. p. 7&lt;/ref&gt;&lt;ref name=&quot;iaf-ifa.org&quot;/&gt;&lt;ref&gt;&quot;That is why Anarchy, when it works to destroy authority in all its aspects, when it demands the abrogation of laws and the abolition of the mechanism that serves to impose them, when it refuses all hierarchical organisation and preaches free agreement — at the same time strives to maintain and enlarge the precious kernel of social customs without which no human or animal society can exist.&quot; [[Peter Kropotkin]]. [http://www.theanarchistlibrary.org/HTML/Petr_Kropotkin__Anarchism__its_philosophy_and_ideal.html Anarchism: its philosophy and ideal]&lt;/ref&gt;&lt;ref&gt;&quot;anarchists are opposed to irrational (e.g., illegitimate) authority, in other words, hierarchy — hierarchy being the institutionalisation of authority within a society.&quot; [http://www.theanarchistlibrary.org/HTML/The_Anarchist_FAQ_Editorial_Collective__An_Anarchist_FAQ__03_17_.html#toc2 &quot;B.1 Why are anarchists against authority and hierarchy?&quot;] in [[An Anarchist FAQ]]&lt;/ref&gt; Anarchism considers the [[state (polity)|state]] to be undesirable, unnecessary, and harmful,&lt;ref name=&quot;definition&quot;&gt;
    15. {{cite journal |last=Malatesta|first=Errico|title=Towards Anarchism|journal=MAN!|publisher=International Group of San Francisco|location=Los Angeles|oclc=3930443|url=http://www.marxists.org/archive/malatesta/1930s/xx/toanarchy.htm|archiveurl=https://web.archive.org/web/20121107221404/http://marxists.org/archive/malatesta/1930s/xx/toanarchy.htm|archivedate=7 November 2012 |deadurl=no|authorlink=Errico Malatesta |ref=harv}}
    16.  
    Das Validierungswerkzeug soll die Ausgabe der C Anwendung auf Vollständigkeit und Korrektheit der Daten prüfen. Das geht meiner Meinung nach am besten, wenn die Daten aus den Ausgabe Textdateien gelesen und aus der Quelle "im Speicher" entfernt werden.

    Im Idealfall heißt das für die XML das nur noch Klammern (für Wikitags) und leere Zeilen übrig bleiben, so die Idee:

    Input:
    Code (Text):
    1. {{Use British English|date=January 2014}}
    wobei:
    Code (Text):
    1. Use British English
    Code (Text):
    1. |date=January 2014
    ersetzt werden sollten wenn die Daten in der Ausgabe vorhanden sind.

    Output:
    Code (Text):
    1. {{}}
    Bzw. das die Zeile von den Surroundings befreit wird. Also ohne Klammer leer und somit "korrekt" verarbeitet wurde.


    PS: Das ersetzen soll auch "words.txt" (Wortinhalte) umfassen, so dass der Absatz/Paragraph komplett geleert wird, wenn alle Daten vorhanden sind.
    Geändert von theSplit (25.04.19 um 11:39 Uhr)
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ dwrox.net

  4. #4
    Bot #0384479 Avatar von BurnerR
    Registriert seit
    Jul 2013
    Beiträge
    3.956
    ngb:news Artikel
    1

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    Hier mal ein Ruby-Prototyp.
    Er erwartet einen Hash gegen den er testet und schreibt aktuell nicht in eine Datei, sondern gibt "{{}}" aus wenn er was findet. Wenn er nichts findet würde man entsprechen "" in die Datei schreiben.
    Generell ist es imHo sinnvoller, nicht raus zu streichen, sondern eine leere Datei entsprechend aufzubauen.
    Er liest jede Zeile ein und sucht nach "{{*}}" Einträgen. Jeden Eintrag, z.B. {{Use British English|date=January 2014}}, teilt er dann am "|" auf, iteriert über jeden und schaut, ob er eine Entsprechung im gegebenem Hash (in python: Dictionary) findet.
    Code (Ruby):
    1.  
    2. $match_hash = {
    3.   "Use British English":"",
    4.   "date":"January 2014",
    5.   "pp-move-indef":"",
    6.   "Anarchism sidebar":""}
    7.  
    8. def could_resolve?(array)
    9.   if array.empty?
    10.     return false
    11.   end
    12.   # Might contain single entry most of the time
    13.   array.each do |entry|
    14.     entry.split("|").each do |sub_entry|
    15.       left_side, right_side  = sub_entry.split("=").append("")
    16.       if !$match_hash.has_key?(left_side.to_sym) || $match_hash[left_side.to_sym] != right_side
    17.         return false
    18.       end
    19.     end
    20.   end
    21.   return true
    22. end
    23.  
    24.  
    25. File.readlines('wikitest.xml').each do |line|
    26.   potencial_matches = line.scan(/{{.*}}/).map{|entry| entry.tr('{}', '')}
    27.   if could_resolve?(potencial_matches)
    28.     puts "{{}}"
    29.   end
    30. end
    31.  
    Da der gegebene Hash nur Beispialhaft und unvollständig ist erkennt das Programm aktuell nur {{pp-move-indef}}, {{Use British English|date=January 2014}} und {{Anarchism sidebar}}.

  5. #5
    1998

    Veteran

    (Threadstarter)

    Avatar von theSplit
    Registriert seit
    Aug 2014
    Beiträge
    4.709
    ngb:news Artikel
    1

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    @BurnerR: Also du würdest empfehlen das Pferd andersherum aufzuziehen? Also mit gefundenen Daten eine Datei aufbauen? Zugegeben, scheint simpel, aber das habe ich noch nicht probiert. Dann wäre es aber vielleicht möglich? bzw. sinnvoll das Diffing so etwas wie "Meld" zu überlassen?

    Bezüglich deines Beispiels: Vielleicht war auch mein Beispiel nicht richtig, aber auch normaler Text sollte erfasst werden, nicht nur speziell ein Wikitag Beispiel.
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ dwrox.net

  6. #6
    Bot #0384479 Avatar von BurnerR
    Registriert seit
    Jul 2013
    Beiträge
    3.956
    ngb:news Artikel
    1

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    Zitat Zitat von theSplit Beitrag anzeigen
    @BurnerR: Also du würdest empfehlen das Pferd andersherum aufzuziehen? Also mit gefundenen Daten eine Datei aufbauen?
    Ja, das auf jeden Fall.
    Zitat Zitat von theSplit Beitrag anzeigen
    Bezüglich deines Beispiels: Vielleicht war auch mein Beispiel nicht richtig, aber auch normaler Text sollte erfasst werden, nicht nur speziell ein Wikitag Beispiel.
    Hattest du ja nur ganz kurz im PS angerissen.

    Aber wenn ich dich richtig verstehe ist die reine Logik ohne Input-Output Zeug eine einzelne Zeile. 'text' wäre jeweils eine Zeile der Datei:
    Code (Ruby):
    1.  
    2. text = "This is some Text. It contains stuff like: Commata, colon or Period."
    3. words = Set["This", "some", "It", "contains"]
    4. text.scan(/[a-zA-z]+/).reject{|word| words.include?(word)}.join(' ')
    5.  
    6. # Result:
    7. => "is Text stuff like Commata colon or Period"
    8.  
    scan gibt ein Array mit den matches zurück, in dem Fall Worte. reject gibt die Elemente zurück die nicht in words gefunden wurde. Am ende noch wieder zusammen bauen zu einem einzelnen String, mit leerzeichen getrennt.

    Es wird auch wirklich nur auf Wort-Ebene verglichen, also ein 'xt' in der gegebenen Wortliste würde nicht dazu führen, dass 'Text' entfernt wird.

  7. #7
    1998

    Veteran

    (Threadstarter)

    Avatar von theSplit
    Registriert seit
    Aug 2014
    Beiträge
    4.709
    ngb:news Artikel
    1

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    Das mit dem "reject" sieht per se gut aus und auch genau danach woran ich in Python etwas gescheitert bin - gibt es dafür ein Python äquivalent?
    Sieht aber so aus, als könnte das nach der Logik schon funktionieren... wobei der einzige Haken wäre, das die Wörter UTF-8 und nicht nur Zeichen aus dem englischen Alphabet sind und auch Nummern enthalten können.

    Und was wäre wenn wir einmal "{{Anarchism|Read more}}" und "Anarchism" als Solo Wort haben, bei deinem Beispiel würde, ungeachtet der Tatsache ob entdeckt oder nicht durch die Anwendung beide "Anarchism" herausgefilter werden, korrek? Da einmal im Wortfilter enthalten. Genau das würde aber die Validierung ad absurdum führen.
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ dwrox.net

  8. #8
    Bot #0384479 Avatar von BurnerR
    Registriert seit
    Jul 2013
    Beiträge
    3.956
    ngb:news Artikel
    1

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    In Python würde mal vermutlich 'filter' verwenden: http://book.pythontips.com/en/latest/map_filter.html
    @ UTF-8: Ja, da müsste man etwas genauer hinschauen was solche technischen Details angeht.

    Zu dem Einwand: Meine erste Idee besteht darin, den scan anzupassen und nicht nur nach Worten zu suchen, sondern stattdessen sowas wie das hier herzunehmen:
    Code (Ruby):
    1. text.scan(/[a-zA-z}}{{\|]+/)
    Hab ich jetzt nicht getestet, aber es sollte dann "{{Anarchism|Read more}}" vollständig matchen und dementsprechend nicht in der Wortliste finden.


    Evtl. habe ich mal ne ruhige Stunde und baue etwas.
    Notwendig dafür wäre aber, dass du mir repräsentative Input-Dateien gibst, die Listen gegen die gematcht werden soll und - ganz wichtig - Referenz Output-Dateien die mir zeigen, wie ein korrektes Ergebnis aussehen soll.

    Da ich auch gerade etwas Python lerne würde ich es womöglich sogar in Python schreiben.
    Auch wenn ich ruby deutlich eleganter finde .

  9. #9
    1998

    Veteran

    (Threadstarter)

    Avatar von theSplit
    Registriert seit
    Aug 2014
    Beiträge
    4.709
    ngb:news Artikel
    1

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    @BurnerR: Ich arbeite gerade an einer "Builder" Variante, die die Ausgaben einliest und entsprechend als Vergleich zur Originaldatei stellen soll. Hatte ich vorher nicht versucht.

    Aber lange Rede, kurzer Sinn: Ich würde dir empfehlen das Projekt zu klonen und mit aktuellen Einstellungen mit der Input Enwik (.xml entpackt) - einmal selbst durchlaufen zu lassen. Grund ist, das die Analysedaten mit Output über 3 GB zusammen ergeben (und auch so im Speicher landen). Das kann und will ich nicht zum Download anbieten oder hosten.

    Das ist dann mit der Datenstruktur und was wie erkannt und entfernt werden könnte viel ersichtlicher, als das hier aufzusplitten. Auch wenn ich Fragen gerne beantworten werde.

    Was am Ende drin stehen soll? - gar nichts mehr so fern alles korrekt erkannt wird. Also 0 Daten übrig (so die erste Idee) = 100% Übereinstimmung.

    Außerdem, zur Einfachheit des Verarbeitens, sind nun die Ausgabedaten mit Tabulator getrennt, was das einlesen stark vereinfachen soll, da vermutlich nicht im Text direkt enthalten, und wenn, wäre es, da Stringwerte immer die letzten Einträge sind, im Output, leicht überschaubar.

    --- [2019-04-27 18:24 CEST] Automatisch zusammengeführter Beitrag ---

    Ich poste hier mal eine Rohfassung von dem Builder (noch nicht auf Github Live aktuell), damit man sieht das es vorwärts geht.

    Code:
    1. //------------------------------------------------------------------------------
    2. // Author: Jan Rie <jan@dwrox.net>
    3. //------------------------------------------------------------------------------
    4. #include <stdlib.h>
    5. #include <stdio.h>
    6. #include <stdbool.h>
    7. #include <string.h>
    8. #include <ctype.h>
    9. #include <time.h>
    10. #include <math.h>
    11.  
    12. //------------------------------------------------------------------------------
    13.  
    14. // Switches
    15. #define BEVERBOSE false
    16. #define DEBUG false
    17. #define DOWRITEOUT true
    18. #define LINETOPROCESS 0
    19.  
    20. #define OUTPUTFILE "output.txt"
    21. #define DICTIONARYFILE "words.txt"
    22. #define WIKITAGSFILE "wikitags.txt"
    23. #define XMLTAGFILE "xmltags.txt"
    24. #define XMLDATAFILE "xmldata.txt"
    25. #define ENTITIESFILE "entities.txt"
    26.  
    27. // Buffers
    28. #define ENTRYBUFFER 5120
    29. #define XMLTAG_BUFFER 128
    30.  
    31. // Counts of predefined const datatypes
    32. #define FORMATS 8
    33. #define INDENTS 3
    34. #define TEMPLATES 11
    35. #define TAGTYPES 11
    36. #define TAGCLOSINGS 3
    37. #define MATHTAG 0
    38.  
    39. //------------------------------------------------------------------------------
    40. /*
    41.   Wikipedia data types and such
    42.  
    43.   See for wikitags
    44.   https://en.wikipedia.org/wiki/Help:Wiki_markup
    45.   https://en.wikipedia.org/wiki/Help:Cheatsheet
    46.  
    47.   Reference for templates:
    48.   https://en.wikipedia.org/wiki/Help:Wiki_markup
    49. */
    50.  
    51. const char formatNames[FORMATS][15] = {
    52.   "Bold + Italic",
    53.   "Bold",
    54.   "Italic",
    55.   "Heading 6",
    56.   "Heading 5",
    57.   "Heading 4",
    58.   "Heading 3",
    59.   "Heading 2"
    60. };
    61.  
    62. const char formats[FORMATS][7] = {
    63.   "'''''", // bold + italic
    64.   "'''", // bold
    65.   "''", // italic
    66.   "======", // Heading 6 - heading start
    67.   "=====",
    68.   "====",
    69.   "===",
    70.   "==" // Heading 2 - heading end
    71. };
    72.  
    73. /*
    74.   NOTE: Indents are only used at the beginning of the line!
    75. */
    76. const char indents[INDENTS][2] = {
    77.   "*", // List element, multiple levels, "**" Element of element
    78.   "#", // Numbered list element, multiple levels = "##" "Element of element"
    79.   ":", // "indent 1", multiple levels using ":::" = 3
    80. };
    81.  
    82. const char templates[TEMPLATES][18] = {
    83.   // NOTE: Should we cover template tags as well for shortening?
    84.   "{{-",
    85.   "{{align",
    86.   "{{break",
    87.   "{{clear",
    88.   "{{float",
    89.   "{{stack",
    90.   "{{outdent",
    91.   "{{plainlist",
    92.   "{{fake heading",
    93.   "{{endplainlist",
    94.   "{{unbulleted list"
    95. };
    96.  
    97. const char wikiTagNames[TAGTYPES][19] = {
    98.   "Math type",
    99.   "Definition/Anchor",
    100.   "Table",
    101.   "Category",
    102.   "Media type",
    103.   "File type",
    104.   "Image type",
    105.   "Sound type",
    106.   "Wiktionary",
    107.   "Wikipedia",
    108.   "Link"
    109. };
    110.  
    111. const char elementTypes[TAGTYPES][18] = {
    112.   // NOTE: Handle definitions after, in case we threat, templates too
    113.   "{{math", // https://en.wikipedia.org/wiki/Wikipedia:Rendering_math
    114.   "{{", // Definition => {{Main|autistic savant}}
    115.   "{\t", // Table start => ! (headline), |- (seperation, row/border), | "entry/ column data"
    116.   "[[category:",
    117.   "[[media:", // Media types start
    118.   "[[file:",
    119.   "[[image:", // [[Image:LeoTolstoy.jpg|thumb|150px|[[Leo Tolstoy|Leo Tolstoy]] 1828-1910]]
    120.   "[[sound:", // Media types end
    121.   //"#REDIRECT", // Redirect #REDIRECT [[United States]] (article) --- #REDIRECT [[United States#History]] (section)
    122.   "[[wiktionary:", // [[wiktionary:terrace|terrace]]s
    123.   "[[wikipedia:", // [[Wikipedia:Nupedia and Wikipedia]]
    124.   "[[" // Link => [[Autistic community#Declaration from the autism community|sent a letter to the United Nations]]
    125. };
    126.  
    127. const char tagClosingsTypes[TAGCLOSINGS][3] = {
    128.   "}}",
    129.   "]]",
    130.   "|}"
    131. };
    132.  
    133. //------------------------------------------------------------------------------
    134. // Function declarations
    135. typedef struct xmldatakv {
    136.   char *key;
    137.   char *value;
    138. } xmldatakv;
    139.  
    140. typedef struct entry {
    141.   unsigned short elementType; // 0 XMLTAG, 1 WIKITAG, 2 WORD, 3 ENTITY
    142.   unsigned int dataReaderIndex;
    143.   unsigned int position;
    144.   unsigned int start;
    145.   unsigned int end;
    146.   unsigned int preSpacesCount;
    147.   unsigned int spacesCount;
    148.   unsigned int length;
    149.   unsigned int tagLength;
    150.   unsigned int readerPos;
    151.   short tagType;
    152.   short dataFormatType;
    153.   short ownFormatType;
    154.   bool formatStart;
    155.   bool formatEnd;
    156.   bool isDataNode;
    157.   bool isClosed;
    158.   short xmlDataCount;
    159.   struct xmldatakv *xmlData;
    160.   char *stringData;
    161. } entry;
    162.  
    163. typedef struct collection {
    164.   FILE *outputFile;
    165.   FILE *dictFile;
    166.   FILE *wtagFile;
    167.   FILE *xmltagFile;
    168.   FILE *xmldataFile;
    169.   FILE *entitiesFile;
    170.   unsigned int count;
    171.   struct entry *entries;
    172. } collection;
    173.  
    174. bool readXMLtag(struct collection*);
    175. bool readWord(struct collection*);
    176. bool readEntity(struct collection*);
    177. bool readWikitag(struct collection*);
    178. bool freeEntry(struct collection*, struct entry*);
    179.  
    180. bool freeEntry(struct collection *readerData, struct entry *entryData) {
    181.   for (int i = 0; i < readerData->count; ++i) {
    182.     if (&readerData->entries[i] == entryData) {
    183.       if (i == readerData->count - 1) {
    184.         if (readerData->entries[i].stringData) free(readerData->entries[i].stringData);
    185.        
    186.         for (int j = 0; j < readerData->entries[i].xmlDataCount; ++j) {
    187.           if (readerData->entries[i].xmlData[j].key) free(readerData->entries[i].xmlData[j].key);
    188.           if (readerData->entries[i].xmlData[j].value) free(readerData->entries[i].xmlData[j].value);
    189.         }
    190.  
    191.         if (readerData->entries[i].xmlData) free(readerData->entries[i].xmlData);
    192.  
    193.         readerData->entries = (struct entry *)realloc(readerData->entries, sizeof(struct entry) * readerData->count - 1);
    194.         --readerData->count;
    195.         return true;
    196.       } else {
    197.         if (readerData->entries[i].stringData) free(readerData->entries[i].stringData);
    198.        
    199.         for (int j = 0; j < readerData->entries[i].xmlDataCount; ++j) {
    200.           if (readerData->entries[i].xmlData[j].key) free(readerData->entries[i].xmlData[j].key);
    201.           if (readerData->entries[i].xmlData[j].value) free(readerData->entries[i].xmlData[j].value);
    202.         }
    203.  
    204.         if (readerData->entries[i].xmlData) free(readerData->entries[i].xmlData);
    205.        
    206.         memmove(&readerData->entries[i], &readerData->entries[i + 1], sizeof(struct entry) * (readerData->count - i - 1));
    207.  
    208.         --readerData->count;
    209.         return true;
    210.       }
    211.     }
    212.   }
    213.  
    214.   return false;
    215. }
    216.  
    217. //------------------------------------------------------------------------------
    218. // Main routine
    219. int main(int argc, char *argv[]) {
    220.   printf("[ INFO ] Starting transpilling on file \"%s\".\n", OUTPUTFILE);
    221.  
    222.   FILE *outputFile = fopen(OUTPUTFILE, "wb");
    223.   FILE *dictFile = fopen(DICTIONARYFILE, "rb");
    224.   FILE *wtagFile = fopen(WIKITAGSFILE, "rb");
    225.   FILE *xmltagFile = fopen(XMLTAGFILE, "rb");
    226.   FILE *xmldataFile = fopen(XMLDATAFILE, "rb");
    227.   FILE *entitiesFile = fopen(ENTITIESFILE, "rb");
    228.  
    229.   struct collection readerData = {outputFile, dictFile, wtagFile, xmltagFile, xmldataFile, entitiesFile, 0, NULL};
    230.   // 0 XMLTAG, 1 WIKITAG, 2 WORD, 3 ENTITY
    231.  
    232.   bool hasXMLTag = false;
    233.   bool hasWikiTag = false;
    234.   bool hasWord = false;
    235.   bool hasEntity = false;
    236.  
    237.   hasXMLTag = readXMLtag(&readerData);
    238.   hasWikiTag = readWikitag(&readerData);
    239.   hasWord = readWord(&readerData);
    240.   hasEntity = readEntity(&readerData);
    241.  
    242.  
    243.   printf("0: %s\n", readerData.entries[0].stringData);
    244.   printf("1: %s\n", readerData.entries[1].stringData);
    245.   printf("2: %s\n", readerData.entries[2].stringData);
    246.   freeEntry(&readerData, &readerData.entries[2]);
    247.   printf("2: %s\n", readerData.entries[2].stringData);
    248.   freeEntry(&readerData, &readerData.entries[2]);
    249.   printf("1: %s\n", readerData.entries[1].stringData);
    250.  
    251.   if (hasXMLTag) {
    252.  
    253.   }
    254.  
    255.   // time_t startTime = time(NULL);
    256.  
    257.   // Cleanup
    258.   fclose(readerData.outputFile);
    259.   fclose(readerData.dictFile);
    260.   fclose(readerData.wtagFile);
    261.   fclose(readerData.xmltagFile);
    262.   fclose(readerData.xmldataFile);
    263.   fclose(readerData.entitiesFile);
    264.  
    265.   for (int i = 0; i < readerData.count; ++i) {
    266.     if (readerData.entries[i].stringData) free(readerData.entries[i].stringData);
    267.  
    268.     for (int j = 0; j < readerData.entries[i].xmlDataCount; ++j) {
    269.       if (readerData.entries[i].xmlData[j].key) free(readerData.entries[i].xmlData[j].key);
    270.       if (readerData.entries[i].xmlData[j].value) free(readerData.entries[i].xmlData[j].value);
    271.     }
    272.  
    273.     if (readerData.entries[i].xmlData) free(readerData.entries[i].xmlData);
    274.   }
    275.  
    276.   free(readerData.entries);
    277.   return 0;
    278. }
    279.  
    280. //------------------------------------------------------------------------------
    281.  
    282. bool readWikitag(struct collection *readerData) {
    283.   if ((readerData->entries = (struct entry *)realloc(readerData->entries, sizeof(struct entry) * (readerData->count + 1))) == NULL) {
    284.     return false;
    285.   }
    286.  
    287.   int returnValue = 0;
    288.   struct entry *element = &readerData->entries[readerData->count];
    289.   element->elementType = 1;
    290.   element->stringData = NULL;
    291.   element->xmlData = NULL;
    292.   element->xmlDataCount = 0;
    293.   element->dataReaderIndex = readerData->count;
    294.   ++readerData->count;
    295.  
    296.   returnValue = fscanf(readerData->wtagFile, "%u\t%u\t%u\t%d\t%d\t%hi\t%hi\t%hi\t%d\t%d\t%d\t%d\t", &element->position, &element->start, &element->readerPos, &element->preSpacesCount, &element->spacesCount, &element->tagType, &element->dataFormatType, &element->ownFormatType, (int *)(bool *)&element->formatStart, (int *)(bool *)&element->formatEnd, &element->tagLength, &element->length);
    297.  
    298.   if (returnValue == EOF)
    299.     return false;
    300.  
    301.   element->stringData = malloc(sizeof(char) * (element->length + 1));
    302.   returnValue = fscanf(readerData->wtagFile, "%s\n", element->stringData);
    303.  
    304.   if (returnValue == EOF)
    305.     return false;
    306.  
    307.   return true;
    308. }
    309.  
    310. //------------------------------------------------------------------------------
    311.  
    312. bool readXMLtag(struct collection *readerData) {
    313.   if ((readerData->entries = (struct entry *)realloc(readerData->entries, sizeof(struct entry) * (readerData->count + 1))) == NULL) {
    314.     return false;
    315.   }
    316.  
    317.   int returnValue = 0;
    318.   struct entry *element = &readerData->entries[readerData->count];
    319.   element->elementType = 0;
    320.   element->stringData = NULL;
    321.   element->start = 0;
    322.   element->end = 0;
    323.   element->isClosed = false;
    324.   element->isDataNode = false;
    325.   element->xmlData = NULL;
    326.   element->xmlDataCount = 0;
    327.   element->dataReaderIndex = readerData->count;
    328.  
    329.   returnValue = fscanf(readerData->xmltagFile, "%d\t%d\t%d\t%d\t", &element->start, &element->end, (int *)(bool *)&element->isClosed, (int *)(bool *)&element->isDataNode);
    330.  
    331.   if (returnValue == EOF)
    332.     return false;
    333.  
    334.  
    335.   element->stringData = malloc(sizeof(char) * XMLTAG_BUFFER);
    336.  
    337.   unsigned int start = 0;
    338.   unsigned int end = 0;
    339.   char tmpKey[128] = "\0";
    340.   char tmpValue[1024] = "\0";
    341.  
    342.   unsigned int readBytes = 0;
    343.  
    344.   while (true) {
    345.     readBytes = ftell(readerData->xmldataFile);
    346.     returnValue = fscanf(readerData->xmldataFile, "%d\t%d\t", &start, &end);
    347.     if (returnValue == EOF)
    348.       break;
    349.  
    350.     if (start == element->start && end == element->end) {
    351.       fscanf(readerData->xmldataFile, "%s\t%s", tmpKey, tmpValue);
    352.       element->xmlData = (struct xmldatakv *)realloc(element->xmlData, sizeof(struct xmldatakv) * (element->xmlDataCount + 1));
    353.  
    354.       element->xmlData[element->xmlDataCount].key = malloc(sizeof(char) * (strlen(tmpKey) + 1));
    355.       strcpy(element->xmlData[element->xmlDataCount].key, tmpKey);
    356.  
    357.       element->xmlData[element->xmlDataCount].value = malloc(sizeof(char) * (strlen(tmpValue) + 1));
    358.       strcpy(element->xmlData[element->xmlDataCount].value, tmpValue);
    359.  
    360.       ++element->xmlDataCount;
    361.  
    362.       printf("xmlData =>\t%s\t==>\t%s\n", tmpKey, tmpValue);
    363.     } else {
    364.       fseek(readerData->xmldataFile, ftell(readerData->xmldataFile) - readBytes, SEEK_SET);
    365.       break;
    366.     }
    367.   }
    368.  
    369.   returnValue = fscanf(readerData->xmltagFile, "%s\n", element->stringData);
    370.   if (returnValue == EOF)
    371.     return false;
    372.  
    373.   ++readerData->count;
    374.   return true;
    375. }
    376.  
    377. //------------------------------------------------------------------------------
    378.  
    379. bool readWord(struct collection *readerData) {
    380.   if ((readerData->entries = (struct entry *)realloc(readerData->entries, sizeof(struct entry) * (readerData->count + 1))) == NULL) {
    381.     return false;
    382.   }
    383.  
    384.   int returnValue = 0;
    385.   struct entry *element = &readerData->entries[readerData->count];
    386.   element->elementType = 2;
    387.   element->stringData = NULL;
    388.   element->xmlData = NULL;
    389.   element->xmlDataCount = 0;
    390.   element->dataReaderIndex = readerData->count;
    391.   ++readerData->count;
    392.  
    393.   returnValue = fscanf(readerData->dictFile, "%u\t%u\t%u\t%u\t%u\t%u\t%hi\t%hi\t%d\t%d\t%d\t%d\t", &element->position, &element->start, &element->readerPos, &element->preSpacesCount, &element->spacesCount, &element->length, &element->dataFormatType, &element->ownFormatType, (int*)(bool*)&element->formatStart, (int*)(bool*)&element->formatEnd, (int*)(bool*)&element->isDataNode, (int*)(bool*)&element->isClosed);
    394.  
    395.   if (returnValue == EOF)
    396.     return false;
    397.  
    398.   element->stringData = malloc(sizeof(char) * (element->length + 1));
    399.   returnValue = fscanf(readerData->dictFile, "%s\n", element->stringData);
    400.  
    401.   if (returnValue == EOF)
    402.     return false;
    403.  
    404.   return true;
    405. }
    406.  
    407. //------------------------------------------------------------------------------
    408.  
    409. bool readEntity(struct collection *readerData) {
    410.   if ((readerData->entries = (struct entry *)realloc(readerData->entries, sizeof(struct entry) * (readerData->count + 1))) == NULL) {
    411.     return false;
    412.   }
    413.  
    414.   int returnValue = 0;
    415.   struct entry *element = &readerData->entries[readerData->count];
    416.   element->elementType = 3;
    417.   element->stringData = NULL;
    418.   element->xmlData = NULL;
    419.   element->xmlDataCount = 0;
    420.   element->dataReaderIndex = readerData->count;
    421.   ++readerData->count;
    422.  
    423.   returnValue = fscanf(readerData->entitiesFile, "%u\t%u\t%u\t%d\t%d\t%hi\t%hi\t%d\t%d\t", &element->position, &element->start, &element->readerPos, &element->preSpacesCount, &element->spacesCount, &element->dataFormatType, &element->ownFormatType, (int *)(bool *)&element->formatStart, (int *)(bool *)&element->formatEnd);
    424.  
    425.   if (returnValue == EOF)
    426.     return false;
    427.  
    428.   element->stringData = (char *)realloc(element->stringData, sizeof(char) * 24);
    429.   returnValue = fscanf(readerData->entitiesFile, "%s\n", element->stringData);
    430.  
    431.   if (returnValue == EOF)
    432.     return false;
    433.  
    434.   return true;
    435. }
    436.  
    437. //------------------------------------------------------------------------------
    438.  
    439.  
    440.  
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ dwrox.net

  10. #10
    Bot #0384479 Avatar von BurnerR
    Registriert seit
    Jul 2013
    Beiträge
    3.956
    ngb:news Artikel
    1

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    Vielleicht schaue ich es mir mal an.
    Aber klingt so als wenn ich C-Code durcharbeiten muss, dann kompilieren und ausführen muss, Ergebnis angucken musst und dann irgendwie eine Zielvorgabe definieren muss. Ich weiß nicht, ob ich darauf Lust habe.
    Lust hätte ich eher, an einer konkreten Aufgabe zur Aufbereitung der Dateien mit Python zu arbeiten.

  11. #11
    1998

    Veteran

    (Threadstarter)

    Avatar von theSplit
    Registriert seit
    Aug 2014
    Beiträge
    4.709
    ngb:news Artikel
    1

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    @BurnerR - hier die Rohdaten aus der Analyse, gepackt: https://dwrox.net/wicked_rawdata.tar.gz
    Vielleicht kannst du damit mehr anfangen?

    Und auch mal der aktuelle, allerdings nicht 100% fehlerfreie und niht optimale, Stand eines Filebuilders aus den gewonnenen Daten:

    Allerdings ist diese Version noch nicht 100% fehlerfrei, ich debugge gerade noch ein Memory Leak bzw. Error....

    Vielleicht mag sich jemand den Code genauer ansehen - speziell ob und wie man das
    Code (C):
    1. while (readWord(&readerData, WORD) { if (........) break; }
    wegoptimieren kann?

    Meine Idee wäre noch die Daten vor der Rückübersetzung zu sortieren, so das alle Daten fortlaufend korrekt gelistet werden ohne das man innerhalb der Datei eine Suchlauf mit Vorsprung für X Einträge/Elemente machen muß.

    verbessern, entfernen kann.

    Code:
    1. //------------------------------------------------------------------------------
    2. // Author: Jan Rie <jan@dwrox.net>
    3. //------------------------------------------------------------------------------
    4. #include <stdlib.h>
    5. #include <stdio.h>
    6. #include <stdbool.h>
    7. #include <string.h>
    8. #include <ctype.h>
    9. #include <time.h>
    10. #include <math.h>
    11.  
    12. //------------------------------------------------------------------------------
    13.  
    14. // Switches
    15. #define DEBUG false
    16. #define VERBOSE false
    17. #define DOWRITEOUT true
    18. #define LINESTOPROCESS 0
    19. #define LOOKAHEADRANGE 2000
    20. #define IDENTATIONBUFFER 33
    21.  
    22. #define OUTPUTFILE "output.txt"
    23. #define DICTIONARYFILE "words.txt"
    24. #define WIKITAGSFILE "wikitags.txt"
    25. #define XMLTAGFILE "xmltags.txt"
    26. #define XMLDATAFILE "xmldata.txt"
    27. #define ENTITIESFILE "entities.txt"
    28.  
    29. // Buffers
    30. #define XMLTAG_BUFFER 5120
    31.  
    32. // Counts of predefined const datatypes
    33. #define FORMATS 8
    34. #define ENTITIES 211
    35. #define INDENTS 3
    36. #define TEMPLATES 11
    37. #define TAGTYPES 11
    38. #define TAGCLOSINGS 3
    39. #define MATHTAG 0
    40.  
    41. //------------------------------------------------------------------------------
    42. /*
    43.   Wikipedia data types and such
    44.  
    45.   See for wikitags
    46.   https://en.wikipedia.org/wiki/Help:Wiki_markup
    47.   https://en.wikipedia.org/wiki/Help:Cheatsheet
    48.  
    49.   Reference for templates:
    50.   https://en.wikipedia.org/wiki/Help:Wiki_markup
    51. */
    52.  
    53. const char formatNames[FORMATS][15] = {
    54.   "Bold + Italic",
    55.   "Bold",
    56.   "Italic",
    57.   "Heading 6",
    58.   "Heading 5",
    59.   "Heading 4",
    60.   "Heading 3",
    61.   "Heading 2"
    62. };
    63.  
    64. const char formats[FORMATS][7] = {
    65.   "'''''", // bold + italic
    66.   "'''", // bold
    67.   "''", // italic
    68.   "======", // Heading 6 - heading start
    69.   "=====",
    70.   "====",
    71.   "===",
    72.   "==" // Heading 2 - heading end
    73. };
    74.  
    75. /*
    76.   NOTE: Indents are only used at the beginning of the line!
    77. */
    78. const char indents[INDENTS][2] = {
    79.   "*", // List element, multiple levels, "**" Element of element
    80.   "#", // Numbered list element, multiple levels = "##" "Element of element"
    81.   ":", // "indent 1", multiple levels using ":::" = 3
    82. };
    83.  
    84. const char templates[TEMPLATES][18] = {
    85.   // NOTE: Should we cover template tags as well for shortening?
    86.   "{{-",
    87.   "{{align",
    88.   "{{break",
    89.   "{{clear",
    90.   "{{float",
    91.   "{{stack",
    92.   "{{outdent",
    93.   "{{plainlist",
    94.   "{{fake heading",
    95.   "{{endplainlist",
    96.   "{{unbulleted list"
    97. };
    98.  
    99. const char wikiTagNames[TAGTYPES][19] = {
    100.   "Math type",
    101.   "Definition/Anchor",
    102.   "Table",
    103.   "Category",
    104.   "Media type",
    105.   "File type",
    106.   "Image type",
    107.   "Sound type",
    108.   "Wiktionary",
    109.   "Wikipedia",
    110.   "Link"
    111. };
    112.  
    113. const char tagTypes[TAGTYPES][18] = {
    114.   // NOTE: Handle definitions after, in case we threat, templates too
    115.   "{{math", // https://en.wikipedia.org/wiki/Wikipedia:Rendering_math
    116.   "{{", // Definition => {{Main|autistic savant}}
    117.   "{\t", // Table start => ! (headline), |- (seperation, row/border), | "entry/ column data"
    118.   "[[category:",
    119.   "[[media:", // Media types start
    120.   "[[file:",
    121.   "[[image:", // [[Image:LeoTolstoy.jpg|thumb|150px|[[Leo Tolstoy|Leo Tolstoy]] 1828-1910]]
    122.   "[[sound:", // Media types end
    123.   //"#REDIRECT", // Redirect #REDIRECT [[United States]] (article) --- #REDIRECT [[United States#History]] (section)
    124.   "[[wiktionary:", // [[wiktionary:terrace|terrace]]s
    125.   "[[wikipedia:", // [[Wikipedia:Nupedia and Wikipedia]]
    126.   "[[" // Link => [[Autistic community#Declaration from the autism community|sent a letter to the United Nations]]
    127. };
    128.  
    129. const char tagClosingsTypes[TAGCLOSINGS][3] = {
    130.   "}}",
    131.   "]]",
    132.   "|}"
    133. };
    134.  
    135. //------------------------------------------------------------------------------
    136.  
    137. typedef struct xmldatakv {
    138.   char *key;
    139.   char *value;
    140. } xmldatakv;
    141.  
    142. typedef struct entry {
    143.   unsigned short elementType; // 0 XMLTAG, 1 WIKITAG, 2 WORD, 3 ENTITY
    144.   unsigned int position;
    145.   unsigned int connectedTag;
    146.   unsigned int start;
    147.   unsigned int end;
    148.   unsigned int preSpacesCount;
    149.   unsigned int spacesCount;
    150.   unsigned int length;
    151.   unsigned int tagLength;
    152.   short tagType;
    153.   short dataFormatType;
    154.   short ownFormatType;
    155.   short hasPipe;
    156.   short isHandledTag;
    157.   short isDataNode;
    158.   short isClosed;
    159.   short xmlDataCount;
    160.   int formatStart;
    161.   int formatEnd;
    162.   struct xmldatakv *xmlData;
    163.   char *stringData;
    164. } entry;
    165.  
    166. typedef struct collection {
    167.   FILE *outputFile;
    168.   FILE *dictFile;
    169.   FILE *wtagFile;
    170.   FILE *xmltagFile;
    171.   FILE *xmldataFile;
    172.   FILE *entitiesFile;
    173.   long int dictSize;
    174.   long int wtagSize;
    175.   long int xmltagSize;
    176.   long int xmldataSize;
    177.   long int entitiesSize;
    178.   long int readDict;
    179.   long int readwtag;
    180.   long int readxmltag;
    181.   long int readxmldata;
    182.   long int readentities;
    183.   unsigned int countWords;
    184.   unsigned int countWtag;
    185.   unsigned int countXmltag;
    186.   unsigned int countEntities;
    187.   struct entry *entriesWords;
    188.   struct entry *entriesWtag;
    189.   struct entry *entriesXmltag;
    190.   struct entry *entriesEntities;
    191. } collection;
    192.  
    193. enum dataTypes {
    194.     XMLTAG = 0,
    195.     WIKITAG = 1,
    196.     WORD = 2,
    197.     ENTITY = 3
    198. };
    199.  
    200. //------------------------------------------------------------------------------
    201. // Function declarations
    202. bool readXMLtag(struct collection*);
    203. bool readWord(struct collection*);
    204. bool readEntity(struct collection*);
    205. bool readWikitag(struct collection*);
    206.  
    207. bool freeEntryByLine(struct collection*, short, unsigned int, unsigned int);
    208. struct entry* getEntryByType(struct collection*, short);
    209. struct entry* getInLine(struct collection*, short, unsigned int, unsigned int);
    210.  
    211. // ----------------------------------------------------------------------------
    212.  
    213. bool freeEntryByLine(struct collection *readerData, short elementType, unsigned int lineNum, unsigned int position) {
    214.   unsigned int count = 0;
    215.   struct entry* items = NULL;
    216.   if (elementType == XMLTAG) {
    217.     count = readerData->countXmltag;
    218.     items = readerData->entriesXmltag;
    219.   } else if (elementType == WORD) {
    220.     count = readerData->countWords;
    221.     items = readerData->entriesWords;
    222.   } else if (elementType == WIKITAG) {
    223.     count = readerData->countWtag;
    224.     items = readerData->entriesWtag;
    225.   } else {
    226.     count = readerData->countEntities;
    227.     items = readerData->entriesEntities;
    228.   }
    229.  
    230.   if (count == 1) {
    231.     if ((items[0].start == lineNum || items[0].end == lineNum) && items[0].position == position) {
    232.       if (items[0].stringData) free(items[0].stringData);
    233.  
    234.       if (elementType == XMLTAG) {
    235.         for (unsigned int j = 0; j < items[0].xmlDataCount; ++j) {
    236.           if (items[0].xmlData[j].key) free(items[0].xmlData[j].key);
    237.           if (items[0].xmlData[j].value) free(items[0].xmlData[j].value);
    238.         }
    239.  
    240.         if (items[0].xmlData) free(items[0].xmlData);
    241.       }
    242.  
    243.  
    244.       items = (struct entry *) realloc(items, sizeof(struct entry) * count);
    245.       --count;
    246.  
    247.       if (elementType == XMLTAG) {
    248.         readerData->countXmltag = count;
    249.         readerData->entriesXmltag = items;
    250.       } else if (elementType == WORD) {
    251.         readerData->countWords = count;
    252.         readerData->entriesWords  = items;
    253.       } else if (elementType == WIKITAG) {
    254.         readerData->countWtag = count;
    255.         readerData->entriesWtag  = items;
    256.       } else {
    257.         readerData->countEntities = count;
    258.         readerData->entriesEntities  = items;
    259.       }
    260.       return true;
    261.     }
    262.   }
    263.  
    264.   for (unsigned int i = count - 1; i != 0; --i) {
    265.     if ((items[i].start == lineNum || items[i].end == lineNum) && items[i].position == position) {
    266.       if (i == count - 1) {
    267.         if (items[i].stringData) free(items[i].stringData);
    268.  
    269.         if (elementType == XMLTAG) {
    270.           for (unsigned int j = 0; j < items[i].xmlDataCount; ++j) {
    271.             if (items[i].xmlData[j].key) free(items[i].xmlData[j].key);
    272.             if (items[i].xmlData[j].value) free(items[i].xmlData[j].value);
    273.           }
    274.  
    275.           if (items[i].xmlData) free(items[i].xmlData);
    276.         }
    277.  
    278.         items = (struct entry *) realloc(items, sizeof(struct entry) * count);
    279.         --count;
    280.  
    281.         if (elementType == XMLTAG) readerData->countXmltag = count;
    282.         else if (elementType == WORD) readerData->countWords = count;
    283.         else if (elementType == WIKITAG) readerData->countWtag = count;
    284.         else readerData->countEntities = count;
    285.  
    286.         return true;
    287.       } else {
    288.         if (items[i].stringData) free(items[i].stringData);
    289.  
    290.         if (elementType == XMLTAG) {
    291.           for (unsigned int j = 0; j < items[i].xmlDataCount; ++j) {
    292.             if (items[i].xmlData[j].key) free(items[i].xmlData[j].key);
    293.             if (items[i].xmlData[j].value) free(items[i].xmlData[j].value);
    294.           }
    295.  
    296.           if (items[i].xmlData) free(items[i].xmlData);
    297.         }
    298.  
    299.         memmove(&items[i], &items[i + 1], sizeof(struct entry) * (count - i - 1));
    300.         --count;
    301.  
    302.         if (elementType == XMLTAG) readerData->countXmltag = count;
    303.         else if (elementType == WORD) readerData->countWords = count;
    304.         else if (elementType == WIKITAG) readerData->countWtag = count;
    305.         else readerData->countEntities = count;
    306.         return true;
    307.       }
    308.     }
    309.   }
    310.  
    311.   return false;
    312. }
    313.  
    314. //------------------------------------------------------------------------------
    315.  
    316. struct entry* getEntryByType(struct collection *readerData, short elementType) {
    317.   if (elementType == XMLTAG) {
    318.     if (readerData->countXmltag == 0) return NULL;
    319.     return &readerData->entriesXmltag[readerData->countXmltag - 1];
    320.   } else if (elementType == WORD) {
    321.     if (readerData->countWords == 0) return NULL;
    322.     return &readerData->entriesWords[readerData->countWords - 1];
    323.   } else if (elementType == WIKITAG) {
    324.     if (readerData->countWtag == 0) return NULL;
    325.     return &readerData->entriesWtag[readerData->countWtag - 1];
    326.   } else {
    327.     if (readerData->countEntities == 0) return NULL;
    328.     return &readerData->entriesEntities[readerData->countEntities - 1];
    329.   }
    330.  
    331.   return NULL;
    332. }
    333.  
    334. //------------------------------------------------------------------------------
    335.  
    336. struct entry* getInLine(struct collection *readerData, short elementType, unsigned int lineNum, unsigned int position) {
    337.   unsigned int count = 0;
    338.   struct entry* items = NULL;
    339.   if (elementType == XMLTAG) {
    340.     count = readerData->countXmltag;
    341.     items = readerData->entriesXmltag;
    342.   } else if (elementType == WORD) {
    343.     count = readerData->countWords;
    344.     items = readerData->entriesWords;
    345.   } else if (elementType == WIKITAG) {
    346.     count = readerData->countWtag;
    347.     items = readerData->entriesWtag;
    348.   } else {
    349.     count = readerData->countEntities;
    350.     items = readerData->entriesEntities;
    351.   }
    352.  
    353.   if (count == 0) return NULL;
    354.  
    355.   if (position != 0) {
    356.     for (unsigned int i = 0 ; i < count; ++i) {
    357.       if (items[i].start == lineNum && items[i].end == lineNum && items[i].position == position) return &items[i];
    358.     }
    359.   } else {
    360.     for (unsigned int i = 0 ; i < count; ++i) {
    361.       if (items[i].start == lineNum || items[i].end == lineNum) return &items[i];
    362.     }
    363.   }
    364.  
    365.   return NULL;
    366. }
    367.  
    368.  
    369. //------------------------------------------------------------------------------
    370. // Main routine
    371. int main(int argc, char *argv[]) {
    372.   printf("[ INFO ] Starting transpilling on file \"%s\".\n", OUTPUTFILE);
    373.  
    374.   FILE *outputFile = fopen(OUTPUTFILE, "wb");
    375.   FILE *dictFile = fopen(DICTIONARYFILE, "rb");
    376.   FILE *wtagFile = fopen(WIKITAGSFILE, "rb");
    377.   FILE *xmltagFile = fopen(XMLTAGFILE, "rb");
    378.   FILE *xmldataFile = fopen(XMLDATAFILE, "rb");
    379.   FILE *entitiesFile = fopen(ENTITIESFILE, "rb");
    380.  
    381.   fseek(dictFile, 0, SEEK_END);
    382.   fseek(wtagFile, 0, SEEK_END);
    383.   fseek(xmltagFile, 0, SEEK_END);
    384.   fseek(xmldataFile, 0, SEEK_END);
    385.   fseek(entitiesFile, 0, SEEK_END);
    386.   fpos_t dictFileSize;
    387.   fpos_t wtagFileSize;
    388.   fpos_t xmltagFileSize;
    389.   fpos_t xmldataFileSize;
    390.   fpos_t entitiesFileSize;
    391.  
    392.   fgetpos(dictFile, &dictFileSize);
    393.   fgetpos(wtagFile, &wtagFileSize);
    394.   fgetpos(xmltagFile, &xmltagFileSize);
    395.   fgetpos(xmldataFile, &xmldataFileSize);
    396.   fgetpos(entitiesFile, &entitiesFileSize);
    397.  
    398.   struct collection readerData = { outputFile,
    399.     dictFile, wtagFile, xmltagFile, xmldataFile, entitiesFile,
    400.     dictFileSize.__pos, wtagFileSize.__pos, xmltagFileSize.__pos, xmldataFileSize.__pos, entitiesFileSize.__pos,
    401.     0, 0, 0, 0, 0,
    402.     0, 0, 0, 0,
    403.     NULL, NULL, NULL, NULL
    404.   };
    405.  
    406.   rewind(dictFile);
    407.   rewind(wtagFile);
    408.   rewind(xmltagFile);
    409.   rewind(xmldataFile);
    410.   rewind(entitiesFile);
    411.  
    412.   time_t startTime = time(NULL);
    413.  
    414.   unsigned int lineNum = 1;
    415.   unsigned int position = 1;
    416.  
    417.   bool hasReplaced = false;
    418.   char preSpaces[32];
    419.   char subSpaces[32];
    420.   char indentation[IDENTATIONBUFFER];
    421.   int currentDepth = 0;
    422.   int previousDepth = currentDepth;
    423.   int lastWikiTypePos = -1;
    424.   short lastWikiType = -1;
    425.  
    426.   struct entry* tmp = NULL;
    427.   unsigned int tmpMax = 0;
    428.   struct entry* preTmp = NULL;
    429.   struct entry* closeTag = NULL;
    430.  
    431.   readXMLtag(&readerData);
    432.   readWikitag(&readerData);
    433.   readWord(&readerData);
    434.   readEntity(&readerData);
    435.  
    436.   while (LINESTOPROCESS == 0 || lineNum <= LINESTOPROCESS) {
    437.     hasReplaced = false;
    438.     previousDepth = currentDepth;
    439.  
    440.     #if VERBOSE
    441.     printf("\nLINE NUM: %d - %d\n", lineNum, position);
    442.     for (int i = 0, j = readerData.countXmltag; i < j; ++i) {
    443.       struct entry* item = &readerData.entriesXmltag[i];
    444.       printf("%d ::::: %d/%u --- %u - pipe: %d ===> %s\n", item->elementType, item->start, item->end, item->position, item->hasPipe, item->stringData);
    445.     }
    446.     for (int i = 0, j = readerData.countWtag; i < j; ++i) {
    447.       struct entry* item = &readerData.entriesWtag[i];
    448.       printf("%d ::::: %d/%u --- %u - pipe: %d ===> %s\n", item->elementType, item->start, item->end, item->position, item->hasPipe, item->stringData);
    449.     }
    450.     for (int i = 0, j = readerData.countWords; i < j; ++i) {
    451.       struct entry* item = &readerData.entriesWords[i];
    452.       printf("%d ::::: %d/%u --- %u - pipe: %d ===> %s\n", item->elementType, item->start, item->end, item->position, item->hasPipe, item->stringData);
    453.     }
    454.     for (int i = 0, j = readerData.countEntities; i < j; ++i) {
    455.       struct entry* item = &readerData.entriesEntities[i];
    456.       printf("%d ::::: %d/%u --- %u - pipe: %d ===> %s\n", item->elementType, item->start, item->end, item->position, item->hasPipe, item->stringData);
    457.     }
    458.     #endif
    459.  
    460.     memset(indentation, ' ', IDENTATIONBUFFER);
    461.     indentation[currentDepth * 2] = '\0';
    462.  
    463.     if ((tmp = getInLine(&readerData, XMLTAG, lineNum, 0)) != NULL) {
    464.       if (tmp->start == lineNum && !tmp->isHandledTag) {
    465.         tmp->isHandledTag = true;
    466.  
    467.         #if DEBUG
    468.         printf("%s<%s", indentation, tmp->stringData);
    469.         #endif
    470.  
    471.         #if DOWRITEOUT
    472.         fprintf(outputFile, "%s<%s", indentation, tmp->stringData);
    473.         #endif
    474.  
    475.         for (int j = 0; j < tmp->xmlDataCount; ++j) {
    476.           #if DEBUG
    477.           printf(" %s=\"%s\"", tmp->xmlData[j].key, tmp->xmlData[j].value);
    478.           #endif
    479.  
    480.           #if DOWRITEOUT
    481.           fprintf(outputFile, " %s=\"%s\"", tmp->xmlData[j].key, tmp->xmlData[j].value);
    482.           #endif
    483.         }
    484.  
    485.         if (!tmp->isDataNode) {
    486.           if (tmp->start != tmp->end) {
    487.             #if DEBUG
    488.             printf("%s", ">\n");
    489.             #endif
    490.  
    491.             #if DOWRITEOUT
    492.             fputc('\n', outputFile);
    493.             #endif
    494.           }
    495.         } else {
    496.           #if DEBUG
    497.           printf("%s", ">");
    498.           #endif
    499.  
    500.           #if DOWRITEOUT
    501.           fputc('>', outputFile);
    502.           #endif
    503.  
    504.           if (tmp->end == lineNum) hasReplaced = true;
    505.         }
    506.  
    507.         if (tmp->start == tmp->end) closeTag = tmp;
    508.         else {
    509.           ++currentDepth;
    510.           memset(indentation, ' ', IDENTATIONBUFFER);
    511.           indentation[currentDepth * 2] = '\0';
    512.         }
    513.       } else if (tmp->end == lineNum) {
    514.         closeTag = tmp;
    515.       }
    516.     }
    517.  
    518.     if ((tmp = getInLine(&readerData, WIKITAG, lineNum, position)) != NULL) {
    519.       memset(preSpaces, ' ', sizeof(preSpaces));
    520.       memset(subSpaces, ' ', sizeof(subSpaces));
    521.       preSpaces[tmp->preSpacesCount] = '\0';
    522.       subSpaces[tmp->spacesCount] = '\0';
    523.  
    524.       lastWikiTypePos = tmp->position;
    525.       lastWikiType = tmp->tagType;
    526.       tmpMax = tmp->start + LOOKAHEADRANGE;
    527.  
    528.       #if DEBUG
    529.       printf("%s%s%s", preSpaces, tagTypes[tmp->tagType], tmp->stringData);
    530.       #endif
    531.  
    532.       #if DOWRITEOUT
    533.       fprintf(outputFile, "%s%s%s", preSpaces, tagTypes[tmp->tagType], tmp->stringData);
    534.       #endif
    535.  
    536.       if (tmp->hasPipe) {
    537.         #if DEBUG
    538.         printf("%s", "|");
    539.         #endif
    540.  
    541.         #if DOWRITEOUT
    542.         fputc('|', outputFile);
    543.         #endif
    544.  
    545.       }
    546.  
    547.       while(readWikitag(&readerData)) {
    548.         if ((preTmp = getEntryByType(&readerData, WIKITAG)) != NULL && preTmp->start >= tmpMax) break;
    549.       }
    550.  
    551.       freeEntryByLine(&readerData, WIKITAG, lineNum, position);
    552.       hasReplaced = true;
    553.     }
    554.  
    555.     if ((tmp = getInLine(&readerData, WORD, lineNum, position)) != NULL) {
    556.       memset(preSpaces, ' ', sizeof(preSpaces));
    557.       memset(subSpaces, ' ', sizeof(subSpaces));
    558.       preSpaces[tmp->preSpacesCount] = '\0';
    559.       subSpaces[tmp->spacesCount] = '\0';
    560.  
    561.  
    562.       if (tmp->connectedTag != -1) {
    563.         lastWikiTypePos = tmp->position;
    564.         #if DEBUG
    565.         printf("%s%s%s", preSpaces, tmp->stringData, subSpaces);
    566.         #endif
    567.  
    568.         #if DOWRITEOUT
    569.         fprintf(outputFile, "%s%s%s", preSpaces, tmp->stringData, subSpaces);
    570.         #endif
    571.  
    572.         if (tmp->hasPipe) {
    573.           #if DEBUG
    574.           printf("%s", "|");
    575.           #endif
    576.  
    577.           #if DOWRITEOUT
    578.           fputc('|', outputFile);
    579.           #endif
    580.         }
    581.       } else {
    582.         #if DEBUG
    583.         printf("%s%s%s", preSpaces, tmp->stringData, subSpaces);
    584.         #endif
    585.  
    586.         #if DOWRITEOUT
    587.         fprintf(outputFile, "%s%s%s", preSpaces, tmp->stringData, subSpaces);
    588.         #endif
    589.       }
    590.  
    591.       tmpMax = tmp->start + LOOKAHEADRANGE;
    592.  
    593.       while(readWord(&readerData)) {
    594.         if ((preTmp = getEntryByType(&readerData, WORD)) != NULL && preTmp->start >= tmpMax) break;
    595.       }
    596.  
    597.       freeEntryByLine(&readerData, WORD, lineNum, position);
    598.       hasReplaced = true;
    599.     }
    600.  
    601.     if ((tmp = getInLine(&readerData, ENTITY, lineNum, position)) != NULL) {
    602.       memset(preSpaces, ' ', sizeof(preSpaces));
    603.       memset(subSpaces, ' ', sizeof(subSpaces));
    604.       preSpaces[tmp->preSpacesCount] = '\0';
    605.       subSpaces[tmp->spacesCount] = '\0';
    606.  
    607.       if (tmp->connectedTag != -1) {
    608.         lastWikiTypePos = tmp->position;
    609.         #if DEBUG
    610.         printf("%s%s%s", preSpaces, tmp->stringData, subSpaces);
    611.         #endif
    612.  
    613.         #if DOWRITEOUT
    614.         fprintf(outputFile, "%s%s%s", preSpaces, tmp->stringData, subSpaces);
    615.         #endif
    616.  
    617.         if (tmp->hasPipe) {
    618.           #if DEBUG
    619.           printf("%s", "|");
    620.           #endif
    621.  
    622.           #if DOWRITEOUT
    623.           fputc('|', outputFile);
    624.           #endif
    625.         }
    626.       } else {
    627.         #if DEBUG
    628.         printf("%s%s%s", preSpaces, tmp->stringData, subSpaces);
    629.         #endif
    630.         #if DOWRITEOUT
    631.         fprintf(outputFile, "%s%s%s", preSpaces, tmp->stringData, subSpaces);
    632.         #endif
    633.       }
    634.  
    635.       tmpMax = tmp->start + LOOKAHEADRANGE;
    636.  
    637.       while(readEntity(&readerData)) {
    638.         if ((preTmp = getEntryByType(&readerData, ENTITY)) != NULL && preTmp->start >= tmpMax) break;
    639.       }
    640.  
    641.       freeEntryByLine(&readerData, ENTITY, lineNum, position);
    642.       hasReplaced = true;
    643.     }
    644.  
    645.     if (lastWikiType != -1 && lastWikiTypePos != -1) {
    646.       tmp = getInLine(&readerData, WORD, lineNum, position + 1);
    647.       if (!tmp || (tmp && tmp->connectedTag == -1)) {
    648.         // TODO: Add table closing here.
    649.         char closing[3];
    650.         strcpy(closing, lastWikiType > 3 ? tagClosingsTypes[1] : tagClosingsTypes[0]);
    651.         #if DEBUG
    652.         printf("%s", closing);
    653.         #endif
    654.         #if DOWRITEOUT
    655.         fprintf(outputFile, "%s", closing);
    656.         #endif
    657.  
    658.         lastWikiType = -1;
    659.       }
    660.     }
    661.  
    662.     if (hasReplaced) {
    663.       ++position;
    664.       continue;
    665.     }
    666.  
    667.     if ((closeTag = getInLine(&readerData, XMLTAG, lineNum, 0)) != NULL) {
    668.       if (closeTag != NULL) {
    669.         if (closeTag->isDataNode && closeTag->end == lineNum) {
    670.           #if DEBUG
    671.           printf("</%s>\n", closeTag->stringData);
    672.           #endif
    673.  
    674.           #if DOWRITEOUT
    675.           fprintf(outputFile, "</%s>\n", closeTag->stringData);
    676.           #endif
    677.  
    678.           freeEntryByLine(&readerData, XMLTAG, lineNum, 0);
    679.         } else if (closeTag->end == closeTag->start) {
    680.           #if DEBUG
    681.           printf(" />\n");
    682.           #endif
    683.  
    684.           #if DOWRITEOUT
    685.           fprintf(outputFile, " />\n");
    686.           #endif
    687.  
    688.           freeEntryByLine(&readerData, XMLTAG, lineNum, 0);
    689.         } else if (!closeTag->isDataNode && closeTag->end == lineNum) {
    690.           if (currentDepth != 0) --currentDepth;
    691.           memset(indentation, ' ', IDENTATIONBUFFER);
    692.           indentation[currentDepth * 2] = '\0';
    693.  
    694.           #if DEBUG
    695.           printf( "%s</%s>\n", indentation, closeTag->stringData);
    696.           #endif
    697.  
    698.           #if DOWRITEOUT
    699.           fprintf(outputFile, "%s</%s>\n", indentation, closeTag->stringData);
    700.           #endif
    701.           freeEntryByLine(&readerData, XMLTAG, lineNum, 0);
    702.         } else if (closeTag->start != closeTag->end && closeTag->isDataNode) {
    703.           #if DEBUG
    704.           printf("%s", "\n");
    705.           #endif
    706.           #if DOWRITEOUT
    707.           fputc('\n', outputFile);
    708.           #endif
    709.         }
    710.  
    711.         closeTag = NULL;
    712.         readXMLtag(&readerData);
    713.       }
    714.     } else {
    715.       #if DEBUG
    716.       printf("%s", "\n");
    717.       #endif
    718.  
    719.       #if DOWRITEOUT
    720.       fputc('\n', outputFile);
    721.       #endif
    722.  
    723.       if (currentDepth > 0 && currentDepth == previousDepth) --currentDepth;
    724.     }
    725.  
    726.     position = 1;
    727.     ++lineNum;
    728.   }
    729.  
    730.  
    731.   long int duration = difftime(time(NULL), startTime);
    732.   long int durHours = floor(duration / 3600);
    733.   long int durMinutes = floor((duration % 3600) / 60);
    734.   long int durSeconds = (duration % 3600) % 60;
    735.   printf("\n\n[STATUS] TRANSPILLING DATA PROCESS: %ldh %ldm %lds\n", durHours, durMinutes, durSeconds);
    736.   // Cleanup
    737.   fclose(readerData.outputFile);
    738.   fclose(readerData.dictFile);
    739.   fclose(readerData.wtagFile);
    740.   fclose(readerData.xmltagFile);
    741.   fclose(readerData.xmldataFile);
    742.   fclose(readerData.entitiesFile);
    743.  
    744.   for (unsigned int i = 0; i < readerData.countXmltag; ++i) {
    745.     if (readerData.entriesXmltag[i].stringData) free(readerData.entriesXmltag[i].stringData);
    746.  
    747.     for (unsigned int j = 0; j < readerData.entriesXmltag[i].xmlDataCount; ++j) {
    748.       if (readerData.entriesXmltag[i].xmlData[j].key) free(readerData.entriesXmltag[i].xmlData[j].key);
    749.       if (readerData.entriesXmltag[i].xmlData[j].value) free(readerData.entriesXmltag[i].xmlData[j].value);
    750.     }
    751.  
    752.     if (readerData.entriesXmltag[i].xmlData) free(readerData.entriesXmltag[i].xmlData);
    753.   }
    754.  
    755.   for (unsigned int i = 0; i < readerData.countWords; ++i) {
    756.     if (readerData.entriesWords[i].stringData) free(readerData.entriesWords[i].stringData);
    757.   }
    758.  
    759.   for (unsigned int i = 0; i < readerData.countWtag; ++i) {
    760.     if (readerData.entriesWtag[i].stringData) free(readerData.entriesWtag[i].stringData);
    761.   }
    762.  
    763.   for (unsigned int i = 0; i < readerData.countEntities; ++i) {
    764.     if (readerData.entriesEntities[i].stringData) free(readerData.entriesEntities[i].stringData);
    765.   }
    766.  
    767.   free(readerData.entriesXmltag);
    768.   free(readerData.entriesWords);
    769.   free(readerData.entriesWtag);
    770.   free(readerData.entriesEntities);
    771.   return 0;
    772. }
    773.  
    774. //------------------------------------------------------------------------------
    775.  
    776. bool readXMLtag(struct collection *readerData) {
    777.   if (readerData->readxmltag >= readerData->xmltagSize) return false;
    778.  
    779.   if ((readerData->entriesXmltag = (struct entry *) realloc(readerData->entriesXmltag, sizeof(struct entry) * (readerData->countXmltag + 1))) == NULL) {
    780.     return false;
    781.   }
    782.  
    783.   int returnValue = 0;
    784.   struct entry *element = &readerData->entriesXmltag[readerData->countXmltag];
    785.   element->elementType = XMLTAG;
    786.   element->stringData = NULL;
    787.   element->start = 0;
    788.   element->end = 0;
    789.   element->isClosed = false;
    790.   element->isDataNode = false;
    791.   element->xmlData = NULL;
    792.   element->xmlDataCount = 0;
    793.   element->position = 1;
    794.   element->connectedTag = -1;
    795.   element->isHandledTag = false;
    796.   element->hasPipe = false;
    797.  
    798.   returnValue = fscanf(readerData->xmltagFile, "%u\t%u\t%hi\t%hi\t", &element->start, &element->end, &element->isClosed, &element->isDataNode);
    799.  
    800.   if (returnValue == EOF) return false;
    801.  
    802.   element = &readerData->entriesXmltag[readerData->countXmltag];
    803.   element->stringData = malloc(sizeof(char) * XMLTAG_BUFFER);
    804.  
    805.   unsigned int dataCount = 0;
    806.   unsigned int start = 0;
    807.   unsigned int end = 0;
    808.   char tmpKey[256] = "\0";
    809.   char tmpValue[1280] = "\0";
    810.  
    811.   if (readerData->readxmldata <= readerData->xmldataSize) {
    812.     fpos_t readBytes;
    813.     while (true) {
    814.       fgetpos(readerData->xmldataFile, &readBytes);
    815.       if (readBytes.__pos == readerData->xmldataSize) break;
    816.       returnValue = fscanf(readerData->xmldataFile, "%d\t%d\t", &start, &end);
    817.       if (returnValue == EOF) break;
    818.  
    819.       if (start == element->start && end == element->end) {
    820.         fscanf(readerData->xmldataFile, "%s\t%[^\n]s", tmpKey, tmpValue);
    821.         element = &readerData->entriesXmltag[readerData->countXmltag];
    822.         element->xmlData = (struct xmldatakv *)realloc(element->xmlData, sizeof(struct xmldatakv) * (dataCount + 1));
    823.  
    824.         element->xmlData[dataCount].key = malloc(sizeof(char) * (strlen(tmpKey) + 1));
    825.         strcpy(element->xmlData[dataCount].key, tmpKey);
    826.  
    827.         element->xmlData[dataCount].value = malloc(sizeof(char) * (strlen(tmpValue) + 1));
    828.         strcpy(element->xmlData[dataCount].value, tmpValue);
    829.         ++dataCount;
    830.  
    831.         #if DEBUG
    832.         //printf("xmlData =>\t%s\t==>\t%s\n", tmpKey, tmpValue);
    833.         #endif
    834.       } else {
    835.         fsetpos(readerData->xmldataFile, &readBytes);
    836.         break;
    837.       }
    838.     }
    839.  
    840.     element->xmlDataCount = dataCount;
    841.     fpos_t pos;
    842.     fgetpos(readerData->xmldataFile, &pos);
    843.     readerData->readxmldata = pos.__pos;
    844.  
    845.   }
    846.  
    847.  
    848.   returnValue = fscanf(readerData->xmltagFile, "%[^\n]s\n", element->stringData);
    849.   if (returnValue == EOF) return false;
    850.  
    851.   fpos_t pos;
    852.   fgetpos(readerData->xmltagFile, &pos);
    853.   readerData->xmltagSize = pos.__pos;
    854.  
    855.   readerData->entriesXmltag[readerData->countXmltag] = *element;
    856.   ++readerData->countXmltag;
    857.   return true;
    858. }
    859.  
    860. //------------------------------------------------------------------------------
    861.  
    862. bool readWikitag(struct collection *readerData) {
    863.   if (readerData->readwtag >= readerData->wtagSize) return false;
    864.  
    865.   if ((readerData->entriesWtag = (struct entry *)realloc(readerData->entriesWtag, sizeof(struct entry) * (readerData->countWtag + 1))) == NULL) {
    866.     return false;
    867.   }
    868.  
    869.   int returnValue = 0;
    870.   struct entry *element = &readerData->entriesWtag[readerData->countWtag];
    871.   element->elementType = WIKITAG;
    872.   element->stringData = NULL;
    873.   element->xmlData = NULL;
    874.   element->xmlDataCount = 0;
    875.   element->start = 0;
    876.   element->end = 0;
    877.   element->preSpacesCount = 0;
    878.   element->spacesCount = 0;
    879.   element->position = 0;
    880.   element->connectedTag = -1;
    881.  
    882.   element->tagType = 0;
    883.   element->tagLength = 0;
    884.   element->dataFormatType = -1;
    885.   element->ownFormatType = -1;
    886.   element->formatStart = 0;
    887.   element->formatEnd = 0;
    888.   element->tagLength= 0;
    889.   element->isHandledTag = false;
    890.   element->hasPipe = false;
    891.  
    892.   returnValue = fscanf(readerData->wtagFile, "%u\t%u\t%d\t%d\t%hi\t%hi\t%hi\t%d\t%d\t%d\t%d\t%hi\t", &element->position, &element->start, &element->preSpacesCount, &element->spacesCount, &element->tagType, &element->dataFormatType, &element->ownFormatType, &element->formatStart, &element->formatEnd, &element->tagLength, &element->length, &element->hasPipe);
    893.   if (returnValue == EOF) return false;
    894.  
    895.   element->end = element->start;
    896.  
    897.   element->stringData = malloc(sizeof(char) * (element->length + 1));
    898.   returnValue = fscanf(readerData->wtagFile, "%[^\n]s\n", element->stringData);
    899.   if (returnValue == EOF) return false;
    900.  
    901.   fpos_t pos;
    902.   fgetpos(readerData->wtagFile, &pos);
    903.   readerData->readwtag = pos.__pos;
    904.  
    905.   readerData->entriesWtag[readerData->countWtag] = *element;
    906.   ++readerData->countWtag;
    907.   return true;
    908. }
    909.  
    910. //------------------------------------------------------------------------------
    911.  
    912. bool readWord(struct collection *readerData) {
    913.   if (readerData->readDict >= readerData->dictSize) return false;
    914.  
    915.   if ((readerData->entriesWords = (struct entry *)realloc(readerData->entriesWords, sizeof(struct entry) * (readerData->countWords + 1))) == NULL) {
    916.     return false;
    917.   }
    918.  
    919.   int returnValue = 0;
    920.   struct entry *element = &readerData->entriesWords[readerData->countWords];
    921.   element->elementType = WORD;
    922.   element->stringData = NULL;
    923.   element->xmlData = NULL;
    924.   element->xmlDataCount = 0;
    925.   element->start = 0;
    926.   element->end = 0;
    927.   element->position = 0;
    928.   element->connectedTag = -1;
    929.   element->isHandledTag = false;
    930.   element->hasPipe = false;
    931.  
    932.   returnValue = fscanf(readerData->dictFile, "%u\t%u\t%d\t%u\t%u\t%u\t%hi\t%hi\t%d\t%d\t%hi\t", &element->position, &element->start, &element->connectedTag, &element->preSpacesCount, &element->spacesCount, &element->length, &element->dataFormatType, &element->ownFormatType, &element->formatStart, &element->formatEnd, &element->hasPipe);
    933.  
    934.   element->end = element->start;
    935.  
    936.   if (returnValue == EOF) return false;
    937.  
    938.   element->stringData = malloc(sizeof(char) * (element->length + 1));
    939.   returnValue = fscanf(readerData->dictFile, "%[^\n]s\n", element->stringData);
    940.   if (returnValue == EOF) return false;
    941.  
    942.   fpos_t pos;
    943.   fgetpos(readerData->dictFile, &pos);
    944.   readerData->readDict = pos.__pos;
    945.  
    946.   readerData->entriesWords[readerData->countWords] = *element;
    947.   ++readerData->countWords;
    948.   return true;
    949. }
    950.  
    951. //------------------------------------------------------------------------------
    952.  
    953. bool readEntity(struct collection *readerData) {
    954.   if (&readerData->readentities >= &readerData->entitiesSize) return false;
    955.  
    956.   if ((readerData->entriesEntities = (struct entry *)realloc(readerData->entriesEntities, sizeof(struct entry) * (readerData->countEntities + 1))) == NULL) {
    957.     return false;
    958.   }
    959.  
    960.   int returnValue = 0;
    961.   struct entry *element = &readerData->entriesEntities[readerData->countEntities];
    962.   element->elementType = ENTITY;
    963.   element->stringData = NULL;
    964.   element->xmlData = NULL;
    965.   element->xmlDataCount = 0;
    966.   element->start = 0;
    967.   element->end = 0;
    968.   element->position = 0;
    969.   element->connectedTag = -1;
    970.   element->isHandledTag = false;
    971.   element->hasPipe = false;
    972.  
    973.   returnValue = fscanf(readerData->entitiesFile, "%u\t%u\t%d\t%d\t%d\t%hi\t%hi\t%d\t%d\t%hi\t", &element->position, &element->start, &element->connectedTag, &element->preSpacesCount, &element->spacesCount, &element->dataFormatType, &element->ownFormatType, &element->formatStart, &element->formatEnd, &element->hasPipe);
    974.  
    975.   element->end = element->start;
    976.  
    977.   if (returnValue == EOF) return false;
    978.  
    979.   element->stringData = (char*) realloc(element->stringData, sizeof(char) * 24);
    980.   returnValue = fscanf(readerData->entitiesFile, "%[^\n]s\n", element->stringData);
    981.  
    982.   if (returnValue == EOF) return false;
    983.  
    984.   fpos_t pos;
    985.   fgetpos(readerData->entitiesFile, &pos);
    986.   readerData->readentities = pos.__pos;
    987.  
    988.   readerData->entriesEntities[readerData->countEntities] = *element;
    989.   ++readerData->countEntities;
    990.   return true;
    991. }
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ dwrox.net

  12. #12
    1998

    Veteran

    (Threadstarter)

    Avatar von theSplit
    Registriert seit
    Aug 2014
    Beiträge
    4.709
    ngb:news Artikel
    1

    Thumbs up Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    Die Daten sind nun sortiert ausgegeben, was über eine Stunde gedauert hat.

    Die sortierten Daten finden sich hier:
    https://dwrox.net/wicked_sorted.tar.gz (660 MB)

    Mit den sortierten Daten lässt sich auch viel bequemer arbeiten.


    Im Projekt ist nun auch der Databuilder zu finden, der die Datei Aufbau übernimmt - allerdings noch ohne Formatierungen wie aus Markdown bekannt:

    Speziell dieser Commit:
    https://github.com/jrie/wicked/commi...8ecb8b73b1c6a8
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ dwrox.net

  13. #13
    Mitglied
    Registriert seit
    Aug 2015
    Beiträge
    59

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    Warum schreibst du den Code eigentlich in C?
    Der Code ist bestenfalls unlesbar, schlimmstenfalls voller Fehler, die man aufgrund der nicht-lesbarkeit nicht sieht.
    Welchen Compiler verwendest du denn? Ich kann deinen Code nicht bauen, die .__pos Konstrukte sind nicht gültig. Was sollen die bezwecken?

    Ich möchte gar nicht sagen dass du kein C verwenden sollst, aber andere Programmiersprachen machen einiges einfacher. Vor allem die manuelle Speicherverwaltung bietet sehr viel Potential für Fehler. Egal welche Programmiersprache, du solltest deinen Code besser strukturieren. Deine Funktionen sind viel zu lang, der Programmfluss ist so gut wie nicht erkennbar.

    Noch eine Anmerkung: Du öffnest die Textdateien im Binärmodus. Ich vermute das ist für die Größenberechnung und deine Tests ob du schon am Ende bist, aber beim binär modus bekommst du schnell Probleme mit Zeilenende wenn du dein Programm auf einem anderen System laufen lässt. Ich würde die Textdateien eher im Textmodus öffnen und mich auf EOF verlassen um das ENde zu erkennen.
    Für diesen Beitrag bedanken sich theSplit, BurnerR

  14. #14
    1998

    Veteran

    (Threadstarter)

    Avatar von theSplit
    Registriert seit
    Aug 2014
    Beiträge
    4.709
    ngb:news Artikel
    1

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    @exomo: fpos_t (Link) werden von fgetpos (Link) zurück geliefert werden und die Position in der Datei angeben im "_pos".

    Siehe auch hier: https://en.cppreference.com/w/c/io/fgetpos

    Der Code ist deshalb in C geschrieben, weil ich damit eigentlich recht warm bin. Jede andere Sprache wäre sicherlich auch möglich. Speichermanagement sehe ich nicht als Problem an, es ist zwar möglich das Fehler damit auftreten aber der Code wird daraufhin, ausgiebig, mit Valgrind's Memcheck, getestet.

    Daher sind auch die sortierten Daten vorher verlinkt, damit man auch mit einer anderen Sprache mit den Rohdaten arbeiten könnte. Ich hatte vorher zum Beispiel auch unter Python gearbeitet.

    Bzgl. EOF habe ich mal etwas gehört, dass die Prüfung sehr kostenintensiv sein soll. Deshalb die Dateiposition Counter.

    Dass der Code sehr unstrukturiert ist, liegt dem Fall geschuldet das ich Zeichenbasierend und im Textfluss entscheide, ich vermute du meinst die großen, sehr vielschichtigen, Funktionen in wicked.c ?

    Edit:
    Compiler: gcc version 8.3.0
    Geändert von theSplit (11.05.19 um 15:23 Uhr)
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ dwrox.net

  15. #15
    Mitglied
    Registriert seit
    Aug 2015
    Beiträge
    59

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    Zitat Zitat von theSplit Beitrag anzeigen
    fpos_t (Link) werden von fgetpos (Link) zurück geliefert werden und die Position in der Datei angeben im "_pos".
    Die Doku sagt nichts darüber aus, was fpos_t jetzt genau ist, und es scheint mir, dass es sich um einen "implementation defined" Datentyp handelt. Bei meinem Compiler (mingw gcc 8.1) ist es nämlich als int64 definiert. Die Doku sagt außerdem, dass man außer wieder einem fsetpos aufruf mitzugeben nichts damit tun soll. Richtig wäre es, wenn collection.dictSize usw. auch als fpos_t definiert wären, dann müsstest du nicht __pos verwenden und alle Compiler sollten das akzeptieren. Allerdings funktioniert dann der vergleich mit readentities wohl nicht mehr. Ein Vergleich auf Dateiende ist mit fpos_t nicht vorgesehen.

    Zitat Zitat von theSplit Beitrag anzeigen
    aber der Code wird daraufhin, ausgiebig, mit Valgrind's Memcheck, getestet
    Das ist aber trotzdem keine Garantie dafür dass alles Korrekt ist

    Zitat Zitat von theSplit Beitrag anzeigen
    Bzgl. EOF habe ich mal etwas gehört, dass die Prüfung sehr kostenintensiv sein soll. Deshalb die Dateiposition Counter.
    "Ich habe mal gehört" ist in Bezug auf Performance in C (und auch sonst) ein eher schlechtes Argument. Entweder du hast es gemessen, oder du hast eine Referenz auf ein Dokument von jemand anderem, der das gemessen hat.
    Meine Vermutung (aber ich habe es auch nicht gemessen) ist, dass fgetpos, fsetpos mindestens genauso aufwändig sind, die verwendest du aber oft.

    Zitat Zitat von theSplit Beitrag anzeigen
    Dass der Code sehr unstrukturiert ist, liegt dem Fall geschuldet das ich Zeichenbasierend und im Textfluss entscheide, ich vermute du meinst die großen, sehr vielschichtigen, Funktionen in wicked.c
    Ja, sowohl wicked als auch unwicked haben sehr lange Funktionen. Parser gehören nicht gerade zu den einfachsten Dinge zu implementieren, ich denke aber schon dass man da Teile in Funktionen stecken kann.
    Für diesen Beitrag bedankt sich theSplit

  16. #16
    1998

    Veteran

    (Threadstarter)

    Avatar von theSplit
    Registriert seit
    Aug 2014
    Beiträge
    4.709
    ngb:news Artikel
    1

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    Danke für dein Feedback Exomo - ich glaube das was ich noch im Hinterkopf zu EOF habe: richtig wäre auf "char" EOF zu prüfen und im weiteren dann aber kein extra feof(....datei....) (das war wohl der Performance Killer, weil die lesenden Funktionen ein EOF, in der Regel, selbst liefern.

    Die Rebuilder Version habe ich auch noch etwas optimiert, so dauert das ausgeben circa ~5-8 Minuten weniger bei einer Laufzeit von 70 Minuten bei 70.000 Zeilen. Aber bei 890 Tausend Zeilen, wird das ewig dauern. obwohl die Daten sortiert eingelesen und abgearbeitet werden können.

    . Richtig wäre es, wenn collection.dictSize usw. auch als fpos_t definiert wären, dann müsstest du nicht __pos verwenden und alle Compiler sollten das akzeptieren.
    Das wird so nicht akzeptiert die Daten im struct collection mit "fpos_t" zu definieren, nimmt der Compiler nicht.
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ dwrox.net

  17. #17
    Bot #0384479 Avatar von BurnerR
    Registriert seit
    Jul 2013
    Beiträge
    3.956
    ngb:news Artikel
    1

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    Zitat Zitat von theSplit Beitrag anzeigen
    @BurnerR - hier die Rohdaten aus der Analyse, gepackt: https://dwrox.net/wicked_rawdata.tar.gz
    Vielleicht kannst du damit mehr anfangen?
    Nein, leider nicht.
    Das ist auch völlig ok, wenn du dir die Mühe nicht unbedingt machen willst, ich antworte eigentlich nur um auszuschließen, dass wir aneinander vorbei reden.


    Woran ich Spaß hätte wäre das als Python-Aufgabe zu lösen mit einer konkreten Fragestellung.
    Also so wie du das in beitrag #3 schon angerissen hast.
    Dafür bräuchte ich aber eine Auflistung, was das Programm ganz genau machen soll. Also auf der Ebene 'Gegeben ist hier Liste X da stehen Einträge drin die sehen so aus: ... Gegeben ist außerdem Textdatei Y und da soll jetzt nach den folgenden vier Regeln gesucht werden: ...'



    Aber Dinge wie sich in C-Code einarbeiten... das würde ich nichtmal gegen Geld freiwillig machen.
    Für diesen Beitrag bedankt sich theSplit

  18. #18
    1998

    Veteran

    (Threadstarter)

    Avatar von theSplit
    Registriert seit
    Aug 2014
    Beiträge
    4.709
    ngb:news Artikel
    1

    Smile Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    Alright, ich drösel das ganze mal etwas auf.
    Hier aber mit dem sortierten Datensätzen, weil diese einfacher zu verwerten sind, meiner Meinung nach.

    Also, Grundsätzlich ist die Aufteilung wie folgt, in folgende Textdateien:
    1) xmltags_sort - beinhaltet alle gefundenen XML Tags/Knoten ohne deren Daten sondern nur mit Namen (méhr dazu gleich).
    2) xmldata_sort - beinhaltet alle XML Tag Datenattribute der Knoten
    3) words_sort - alle gefundenen Wörter
    4) wikitags_sort - alle Wikitags (Links, Math-Tags, Referenzen, Überschriften) - mit Hauptschlüssel (andere Attribute sind dann, wenn kein Tag, dann Wörter, sonst Tags)
    5) entities_sort - alle Entities, alos HTML Umlaute, Sonderzeichen, Mathematische Symbole uvm.

    Wie sind die Daten aufgebaut? (Alle Daten sind mit einem Tabulator getrennt, ähnlich einer CSV nur eben mit Tabs als Trenner.
    1) XMLTags

    Spoiler: 

    - ZeileStart (unsigned int)
    - ZeileEnde
    - IstGeschlossen (bool)
    - istWortKnoten (bool)
    - XMLnode Name (string)


    2) XMLDaten

    Spoiler: 

    - ZeileStart
    - ZeileEnde
    - Schlüssel (String)
    - Wert (String)


    Das war das XML, nun die anderen Typen:
    3) Wörter / Words:

    Spoiler: 

    - Position (innerhalb der Zeile) 1 oder 2 oder 12 oder X usw.
    - Zeilennummer
    - Wikitag (als Position falls in Wikitag, sonst -1)
    - PreSpaces (Anzahl Spaces vor einem Wort)
    - Spaces (Anzahl Spaces nach einem Wort)
    - Wortlänge
    - Daten Formattyp (Bold, Italic, Heading)
    - eigener Formattyp (wenn z.b. in Heading, könnte auch bold oder italic sein was nur für dieses Wort gilt)
    - istFormatStart (bool) => Ist Beginn einer Formatierung?
    - istFormatEnde (bool) => Ist Ende einer Formatierung?
    - hasPipe - wird mit "|" eingeleitet (in einem Wikitag)
    - Wort (String)


    4) Wikitags:

    Spoiler: 

    - Position
    - Zeile
    - Wikitag (als Position falls in, anderen, Wikitag enthalten, sonst -1)
    - PreSpaces
    - Spaces
    - Wikitag Typ
    - Daten Formattyp
    - Eigenes Format
    - istFormatStart (bool)
    - istFormatEnde (bool)
    - Wikitag Länge Wikitag (Zeichen)
    - Länge Wikitag (Titel)
    - hasPipe - wird mit "|" eingeleitet (in einem Wikitag)
    - Titel (string)


    5) Entities:

    Spoiler: 

    - Position
    - Zeile
    - Wikitag (als Position falls in, anderen, Wikitag enthalten, sonst -1)
    - PreSpaces
    - Spaces
    - Wikitag Typ
    - Daten Formattyp
    - Eigenes Format
    - istFormatStart (bool)
    - istFormatEnde (bool)
    - Wikitag Länge Wikitag (Zeichen)
    - Länge Wikitag (Titel)
    - hasPipe - wird mit "|" eingeleitet (in einem Wikitag)
    - Wert (Entity HTML Kürzel)


    Und hier Auszüge der Daten als Download im Forum.
    Je die ersten 1000 Einträge/Zeilen:

    xmltags_sort_1k.txt
    xmldata_sort_1k.txt
    words_sort_1k.txt
    wikitags_sort_1k.txt
    entities_sort_1k.txt

    Und hier 1000 Zeilen aus den Rohdaten/dem Original* (die Rawdaten sind nicht sortiert!, bitte das Sort im Dateinamen ignorieren.)
    rawdata_sort_1k.txt

    Was daraus gemacht werden soll? - Nun ja, der Text (rawData_sort_1k) soll aus den sortieren Daten rekonstruiert werden, so gut wie eben möglich. Kleine Abweichungen zum Original wären okay, aber größtenteils sollte aus dem Auszügen das Endprodukt herauskommen können.

    Das heißt, in den Sort Dateien gibt es die Bausteine. Aus denen das Endprodukt herausgearbeitet werden soll.

    Mein erster Ansatz war das ersetzen in einer Originalkopie, dabei gab es allerdings auch ein paar Schwierigkeiten, wie vorher angerissen.
    Geändert von theSplit (12.05.19 um 17:57 Uhr)
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ dwrox.net

  19. #19
    1998

    Veteran

    (Threadstarter)

    Avatar von theSplit
    Registriert seit
    Aug 2014
    Beiträge
    4.709
    ngb:news Artikel
    1

    Re: Hilfe - Datenbereinigung/Validierungswerkzeug

    Folgend ein Fehler behobener, sortierter, Datensatz: https://dwrox.net/wicked_sorted.tar.bz2
    Die vorherige Version hatte Fehler, bei dem die Entities falsch bzw. nicht korrekt, in Wikitags, positioniert waren und somit weniger zusammenhängende Daten gefunden worden sind (rewicked.c.).

    Im weiteren werden für die Position, Zeilennummer und die SpacesCount Angaben alles in Hex geschrieben, was auch nochmal ein paar hundert MB in den Datendaten spart und so gut wie kaum bis keinen direkten Overhead hat - eher ist es schneller geworden.

    --- [2019-05-18 07:08 CEST] Automatisch zusammengeführter Beitrag ---

    @exomo: Habe auch deine Punkte behoben, also kein binäre Daten und kein fgetpos mehr.
    Gruß theSplit
    @ I might be sober. The good things... the bad things... all I ever know is here! @
    +++ thunderNote +++ Thom's Inventarverwaltung +++ Pi-Thread +++ IT-Talents Code Competitions +++ NGB-Statistik Opt-Out/Anonymisierung +++ Stonerhead +++ Add-on Flag Cookies +++ Google Image Directlinks +++ dwrox.net

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •