Marvin Esse: In allen Dateien in Tag Attribut einfügen, wenn nicht vorhanden

Hallo,

ich suche nach einem Tool, mit dem ich in alle Dateien in einem Verzeichnis prüfen kann, ob ein spezieller Tag ein Attribut enthält und wenn nicht, dann automatisch einfügt.

In meinem speziellen Fall sind es eine 5-stellige Anzahl von SVG-Dateien, bei denen bei geschätzt 35% ein Attribut im SVG-Tag fehlt.

Kennt jemand von Euch vielleicht ein Tool, mit dem ich das bewerkstelligen kann?

Ich hab zwar ein paar Tools gefunden, mit denen ich alle Dateien nach einem regulären Ausdruck suchen kann, aber ich weiß nicht, aber dort gibts nur ein Suchen und Ersetzen und ich will ja einfügen und auch nur dann wenn ein Attribut nicht vorhanden ist.

LG Marvin

  1. Kennt jemand von Euch vielleicht ein Tool, mit dem ich das bewerkstelligen kann?

    Mit Node.js + jQuery kannst du dir so ein Tool in kurzer Zeit zusammen hacken. Vorausgesetzt, du kennst dich mit JavaScript schon aus.

    1. Kennt jemand von Euch vielleicht ein Tool, mit dem ich das bewerkstelligen kann?

      Mit Node.js + jQuery kannst du dir so ein Tool in kurzer Zeit zusammen hacken. Vorausgesetzt, du kennst dich mit JavaScript schon aus.

      Klingt interessant. Ohne das jemals gemacht zu haben: birgt das nicht das Risiko, dass das Markup verändert wird (zzgl. der gewünschten Änderung natürlich)?

      1. Hallo und guten Abend,

        wenn ich nicht total schief liege, dann müsste das auch mit dem DOM-Parser von PHP gehen.

        Habe ich gerade eben wieder mit rumgebastelt...

        Erst mal ausprobieren, ob Du den bewussten Tag finden kannst damit. Dann kannst Du auch die Attribute finden, ersetzen oder welche hinzufügen oder entfernen.

        function get_linklist($page, &$_exceptions = NULL)
        {
        	$dom = new DOMDocument('1.0', 'utf-8');
        	$dom->encoding = 'utf-8';
        	$dom->validateOnParse = TRUE;
        	$dom->strictErrorChecking = true ;
        	$dom->preserveWhiteSpace = true;
        	$dom->resolveExternals = true;
        	
        #	die ($dom->actualEncoding);
        	
        	set_error_handler('handleError', E_WARNING);
        	$dom->loadHTML('<meta http-equiv="content-type" content="text/html; charset=utf-8">' . "\r\n" . $page);
        	restore_error_handler();
        	
        	$a_nodelist = $dom->getElementsByTagName('a');
        
        	$_tags = array();	
        	foreach ( $a_nodelist as $index => $node )
        	{
        		if ($node->hasAttributes())
        		{
        			$_attrlist = array();
        			foreach ($node->attributes as $attr)
        			{
        				$_attrlist[$attr->nodeName] = $attr->nodeValue;
        			}
        		}
        
        		if (isset($_attrlist['href']))
        		{
        			$_tags[] = array('href' => $_attrlist['href'], 'text' => $node->textContent);
        		}	
        	}	
        	
        	return $_tags;		
        }
        

        So ginge es für HTML-Dateien. Das SVG-Format entspicht doch dem Muster...

        Grüße
        TS

        --
        es wachse der Freifunk
        http://freifunk-oberharz.de
        1. Hallo,

          ich hab mich heute probiert, die SVG-Dateien zu prüfen (das klappt schonmal) und eine korrigierte Version zu speichern. Leider geht beim Speichern die Formatierung verloren, also Carriage Return und Einschübe. Zusätzlich sieht es so aus, als ob er die ersten zwei Zeilen vertauscht, also aus

          <?xml version="1.0" encoding="iso-8859-1"?>
          <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"    "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
          

          wird

          <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
          <?xml version="1.0" encoding="iso-8859-1"?>
          

          Zudem wird die Zeichnung im IE nicht angezeigt. (Wenn das Atttribut fehlt, dann werden "wenigstens" ein paar Ziffern angezeigt)

          Hat jemand eine Idee?

          Das Script sieht momentan wie folgt aus: Das '@' vor dem LoadHTMLFile habe ich verwendet, da ansonsten die ganzen Tags der SVG-Datei als fehlerhaft angezeigt wurden, da ja kein HTML.

          $verzeichnis = "./svgs";
          if ( is_dir ( $verzeichnis )) {
              if ( $handle = opendir($verzeichnis) ) {
                  while (($file = readdir($handle)) !== false) {
          			$typ = strtoupper(array_pop(explode(".",$file)));
          			if ($typ == "SVG") {
          	            echo "Typ: $typ Datei: $file ";
          				$dom = new DOMDocument('1.0', 'iso-8859-1');
          				$dom->encoding = 'iso-8859-1';
          				$dom->validateOnParse = FALSE;
          				$dom->strictErrorChecking = false ;
          				$dom->preserveWhiteSpace = true;
          				$dom->resolveExternals = true;
          				$dom->formatOutput = true;
          				@$dom->loadHTMLFile($verzeichnis."/".$file);
          				$a_nodelist = $dom->getElementsByTagName('svg');
          				
          				foreach ( $a_nodelist as $index => $node ) {
          					if ($node->hasAttributes()) {
          						$_attrlist = array();
          						foreach ($node->attributes as $attr) {
          							$_attrlist[$attr->nodeName] = $attr->nodeValue;
          						}
          					}
          					if (isset($_attrlist['xmlns'])) {
          						echo "OK <br/>";
          					} else {
          						echo "repariert <br/>";
          						$attr = $node->setAttribute("xmlns","http://www.w3.org/2000/svg");
          						$dom->saveHTMLFile($verzeichnis."/neu/".$file);
          					}
          				}	
          
          			}
                  }
                  closedir($handle);
              }
          }
          
          
          1. Hallo und guten Morgen,

            ich würde das DOM aus einem String laden, und nicht aus einer Datei. Das hat den Vorteil, dass Du die Meta-Angabe für den Content-Type noch vorschalten kannst, wenn sie in der ersten Zeile der Datei nicht enthalten sein sollte.

            Und die Formatierung sollte eigentlich erhalten bleiben. Du hast doch

            $dom->preserveWhiteSpace = true; und $dom->formatOutput = true; eingeschaltet.

            Grüße
            TS

            --
            es wachse der Freifunk
            http://freifunk-oberharz.de
            1. Guten Morgen TS,

              ich würde das DOM aus einem String laden, und nicht aus einer Datei. Das hat den Vorteil, dass Du die Meta-Angabe für den Content-Type noch vorschalten kannst, wenn sie in der ersten Zeile der Datei nicht enthalten sein sollte.

              Das kann ich gerne mal versuchen. Ich hatte mich zwischenzeitlich einfach damit beholfen, die Zeile durch Suchen&Ersetzen erst rauszuwerfen und dann wieder an den Anfang zu setzen. Zusätzlich musste ich auch noch die eingebauten "<html><body>" wieder entfernen, da ansonsten kein valides SVG herauskommt. Ich bekomme zwar die erzeugte SVG-Datei im IE geöffnet und angezeigt (auch wenn leicht unterschiedlich zum Original: etwas kleiner und nicht zentriert), aber wenn ich das SVG weiterverarbeiten möchten (muss), dann erhalte ich sogar eine Fehlermeldung:

              Fehler beim Auslesen der SVG Tag-Attribute. Die Sequenz enthält keine Elemente. Unerwarteter Fehler. Der Pfad darf keine leere Zeichenfolge sein oder nur aus Leerzeichen bestehen.

              Ich vermute aber, dass es durch die fehlenden Umbrüche entsteht und der Parser nicht mehr die gesamte Zeile lesen kann.

              Und die Formatierung sollte eigentlich erhalten bleiben. Du hast doch

              $dom->preserveWhiteSpace = true; und $dom->formatOutput = true; eingeschaltet.

              Tja, leider ist dem aber nicht so.

              LG Marvin

              1. Ich bekomme zwar die erzeugte SVG-Datei im IE geöffnet und angezeigt (auch wenn leicht unterschiedlich zum Original: etwas kleiner und nicht zentriert), aber wenn ich das SVG weiterverarbeiten möchten (muss), dann erhalte ich sogar eine Fehlermeldung:

                Fehler beim Auslesen der SVG Tag-Attribute. Die Sequenz enthält keine Elemente. Unerwarteter Fehler. Der Pfad darf keine leere Zeichenfolge sein oder nur aus Leerzeichen bestehen.

                Ich vermute aber, dass es durch die fehlenden Umbrüche entsteht und der Parser nicht mehr die gesamte Zeile lesen kann.

                Leider konnte ich das nicht bestätigen. Ich habe testweise hinter jedes ">" ein "\r\n" eingefügt. Aber das hatte keinen Einfluss auf den Fehler und ich kann leider nicht den Fehler finden.

                LG Marvin

      2. Klingt interessant. Ohne das jemals gemacht zu haben: birgt das nicht das Risiko, dass das Markup verändert wird (zzgl. der gewünschten Änderung natürlich)?

        Naja, das SVG muss von jQuery geparst und wieder serialisiert werden. Irrelevante Details können dabei verloren gehen, zum Beispiel die Groß-/Kleinschreibung der Tags. Natürlich könnte es auch Bugs im Parser oder Serializer geben, das kann nie gänzlich ausgeschlossen werden. Alles in allem dürfte man damit aber robuster fahren als mir regulären Ausdrücken - die völlig agnostisch von der DOM-Struktur nur Text verarbeiten.

        1. Klingt interessant. Ohne das jemals gemacht zu haben: birgt das nicht das Risiko, dass das Markup verändert wird (zzgl. der gewünschten Änderung natürlich)?

          Naja, das SVG muss von jQuery geparst und wieder serialisiert werden. Irrelevante Details können dabei verloren gehen, zum Beispiel die Groß-/Kleinschreibung der Tags. Natürlich könnte es auch Bugs im Parser oder Serializer geben, das kann nie gänzlich ausgeschlossen werden. Alles in allem dürfte man damit aber robuster fahren als mir regulären Ausdrücken - die völlig agnostisch von der DOM-Struktur nur Text verarbeiten.

          Ich bin da grundsätzlich schon völlig bei Dir, mir fehlt da aber ein Aspekt. Auch die SVG selber können irgendwelche Defekte / Eigenarten haben, die sich über diesen Weg verändern könnten/würden. Das wäre mir zu heiß. Da scheint mir eine textbasierte Fummelei weniger gefährlich. So ein Fummelscript/Aufruf via SED kann man ja auch zur Sichtprüfung durchlaufen lassen.

          1. Ich bin da grundsätzlich schon völlig bei Dir, mir fehlt da aber ein Aspekt. Auch die SVG selber können irgendwelche Defekte / Eigenarten haben, die sich über diesen Weg verändern könnten/würden.

            Garbage in -> Garbage out.

            Das wäre mir zu heiß. Da scheint mir eine textbasierte Fummelei weniger gefährlich. So ein Fummelscript/Aufruf via SED kann man ja auch zur Sichtprüfung durchlaufen lassen.

            Hmm... aber durch das Parsing würden Syntaxfehler in den Eingabe-SVGs immerhin auffliegen. Bei der Textersetzung verschlimmbessert sich die Situation.

            1. Ich bin da grundsätzlich schon völlig bei Dir, mir fehlt da aber ein Aspekt. Auch die SVG selber können irgendwelche Defekte / Eigenarten haben, die sich über diesen Weg verändern könnten/würden.

              Garbage in -> Garbage out.

              Ich bin da nicht sicher. Die Fehlerkorrktur des Clients(Browser) kann zu anderen Ergebnissen kommen als die von JSDOM, was jQuery bei Node.js ja verwendet.

              Das wäre mir zu heiß. Da scheint mir eine textbasierte Fummelei weniger gefährlich. So ein Fummelscript/Aufruf via SED kann man ja auch zur Sichtprüfung durchlaufen lassen.

              Hmm... aber durch das Parsing würden Syntaxfehler in den Eingabe-SVGs immerhin auffliegen.

              Bei SVG ist falsch / richtig die visuelle Darstellung. Die kann sich durch die Verarbeitung verändern. Aktuell scheint sie ja zu stimmen, bzw. so zu sein, wie gewohnt / gewollt.

              Bei der Textersetzung verschlimmbessert sich die Situation.

              Kann, muss aber nicht. Es soll ja "nur" ein Attribut hinzugefügt werden.

  2. Hallo,

    Hi

    ich suche nach einem Tool, mit dem ich in alle Dateien in einem Verzeichnis prüfen kann, ob ein spezieller Tag ein Attribut enthält und wenn nicht, dann automatisch einfügt.

    Welche platform? mit einem kleinen (zb. ruby) script ist das ganz einfach lösbar.

    1. Für jede .svg in $verzeichnis
    2. Datei komplett lesen und parsen (in ruby würde man das z.B. mit Nokogiri machen)
    3. Alle betreffenden tags im DOM suchen,
    4. checken ob das attribut existiert, wenn nicht hinzufügen.
    5. Resultat in einer neuen datei speichern.
    6. Profit.

    In meinem speziellen Fall sind es eine 5-stellige Anzahl von SVG-Dateien, bei denen bei geschätzt 35% ein Attribut im SVG-Tag fehlt.

    Kennt jemand von Euch vielleicht ein Tool, mit dem ich das bewerkstelligen kann?

    Ich hab zwar ein paar Tools gefunden, mit denen ich alle Dateien nach einem regulären Ausdruck suchen kann, aber ich weiß nicht, aber dort gibts nur ein Suchen und Ersetzen und ich will ja einfügen und auch nur dann wenn ein Attribut nicht vorhanden ist.

    Das ginge sicher auch mit tools wie sed, aber da musst du regular expressions benutzen was gewöhnlich zu einer latte von kopfschmerzen und anderen problemen führt.

    LG Marvin

    Ola.

    1. ich suche nach einem Tool, mit dem ich in alle Dateien in einem Verzeichnis prüfen kann, ob ein spezieller Tag ein Attribut enthält und wenn nicht, dann automatisch einfügt.

      Welche platform? mit einem kleinen (zb. ruby) script ist das ganz einfach lösbar.

      1. Für jede .svg in $verzeichnis
      2. Datei komplett lesen und parsen (in ruby würde man das z.B. mit Nokogiri machen)
      3. Alle betreffenden tags im DOM suchen,
      4. checken ob das attribut existiert, wenn nicht hinzufügen.
      5. Resultat in einer neuen datei speichern.
      6. Profit.

      Was aber ebenso wie Toms und Unitedpowers Lösungsvorschlag (scheint mir der eleganste von den dreien) das Markup potentiell weitergehend verändern kann, als nur das Attribut hinzuzufügen. Scheint mir gefährlich.

      Ich hab zwar ein paar Tools gefunden, mit denen ich alle Dateien nach einem regulären Ausdruck suchen kann, aber ich weiß nicht, aber dort gibts nur ein Suchen und Ersetzen und ich will ja einfügen und auch nur dann wenn ein Attribut nicht vorhanden ist.

      Das ginge sicher auch mit tools wie sed, aber da musst du regular expressions benutzen was gewöhnlich zu einer latte von kopfschmerzen und anderen problemen führt.

      In dem Fall würde ich Regexp tatsächlich vorziehen, soweit das Markup der SVG-Dateien auch hinreichend konsitetent und prägnant an der fraglichen Stelle ist.