worker0815
Goto Top

VBS - Blöcke in Array zusammenfassen - Dopplungen löschen

Hallo,

ich brauche bitte mal etwas Hilfestellung.
Ausgangslage - eine XML-Datei vom Tool WinAuthenticator.

Max Mustermann und Mira Musterfrau nutzen das Tool über eine zentrale XML-Datei. (das als Beispiel, die Personenanzahl in Real ist größer)
Die XML-Datei ist quasi bis zum Feierabend im Zugriff.

Karl Musterkind öffnet das Tool, legt sich neu an, und erzeugt damit einen neuen Block in der XML-Datei.
Er schließt das Tool. Die XML-Datei enthält seinen Block.

Schließen nun Max Mustermann oder Mira Musterfrau nach ihm das Tool, wird deren aktueller Stand in die XML-Datei zurück und damit überschrieben.
Karl Musterkind verschwindet.


1. Um dem Herr zu werden, soll alle 5 Minuten ein Skript über die XML-Datei laufen.
2. Alle Blöcke der Personen auslesen und in eine Masterdatei übergeben und dies fortlaufend schreiben.
Man erhält also in Folge nach mehrfacher Ausführung mehrere Blöcke mit doppelten Namensinhalt:
Max Mustermann, Mira Musterfrau, Max Mustermann, Mira Musterfrau, Karl Musterkind, Max Mustermann, Mira Musterfrau, Max Mustermann, Mira Musterfrau, Karl Musterkind
Insofern in Ordnung, da es mitunter sein kann, dass sich ein Person erneut hinzufügt und neue Schlüsselwerte erhält. Selbst löschen kann sie sich nicht.
Von daher wäre der aktuelle Created-Lastuser Zeitstempel wichtig.
3. Die Masterdatei wird gefiltert nach doppelten Blöcken nach Name. Der ältere Block soll gelöscht werden. (da benötige ich Hilfe)

Ich hoffe das war soweit verständlich.

Punkt 1 - mache ich per Aufgabenplanung


Ausgangs-XML:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>  
<WinAuth version="3.7">  
  <alwaysontop>false</alwaysontop>
  <usetrayicon>false</usetrayicon>
  <notifyaction>Notification</notifyaction>
  <startwithwindows>true</startwithwindows>
  <autosize>true</autosize>
  <left>57</left>
  <top>25</top>
  <width>643</width>
  <height>278</height>
  <master><![1[23]]></master>

  <WinAuthAuthenticator id="be2ccecc18f1" type="WinAuth.GoogleAuthenticator">  
    <name>Max Mustermann</name>
    <created>1580897853024</created>
    <lastused>1580897940934</lastused>
    <autorefresh>false</autorefresh>
    <allowcopy>false</allowcopy>
    <copyoncode>false</copyoncode>
    <hideserial>false</hideserial>
    <skin>WinAuthIcon.png</skin>
    <authenticatordata encrypted="y">940C</authenticatordata>  
  </WinAuthAuthenticator>
  <WinAuthAuthenticator id="ff40d1b9d261" type="WinAuth.GoogleAuthenticator">  
    <name>Mira Musterfrau</name>
    <created>1580898599724</created>
    <lastused>1580898599724</lastused>
    <autorefresh>false</autorefresh>
    <allowcopy>false</allowcopy>
    <copyoncode>false</copyoncode>
    <hideserial>false</hideserial>
    <skin>WinAuthIcon.png</skin>
    <authenticatordata encrypted="y">316</authenticatordata>  
  </WinAuthAuthenticator>

</WinAuth>


Mit diesem Skript erledige ich Punkt 2:


Dim FSO, f
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Set FSO = CreateObject("Scripting.FileSystemObject")  
AlleZeilen = Split(FSO.OpenTextFile("grpauth.xml",1).ReadAll,vbcrlf)  
For i = 12 to Ubound(AlleZeilen) - 1
	a = i mod(1)
	if a = WinAuthAuthenticator then
		ZeilenEinzel = ZeilenEinzel & AlleZeilen(i) & vbcrlf
	end if
Next
Set f = FSO.OpenTextFile("Master_02_Mitte_ungefiltert_temp.txt", ForAppending, True)  
f.Write (ZeilenEinzel)
f.Close


Erhalte ich nun folgendes Ergebnis:

  <WinAuthAuthenticator id="be2ccecc18f1" type="WinAuth.GoogleAuthenticator">  
    <name>Max Mustermann</name>
    <created>1580897853024</created>
    <lastused>1580897940934</lastused>
    <autorefresh>false</autorefresh>
    <allowcopy>false</allowcopy>
    <copyoncode>false</copyoncode>
    <hideserial>false</hideserial>
    <skin>WinAuthIcon.png</skin>
    <authenticatordata encrypted="y">940C</authenticatordata>  
  </WinAuthAuthenticator>
  <WinAuthAuthenticator id="ff40d1b9d261" type="WinAuth.GoogleAuthenticator">  
    <name>Mira Musterfrau</name>
    <created>1580898599724</created>
    <lastused>1580898599724</lastused>
    <autorefresh>false</autorefresh>
    <allowcopy>false</allowcopy>
    <copyoncode>false</copyoncode>
    <hideserial>false</hideserial>
    <skin>WinAuthIcon.png</skin>
    <authenticatordata encrypted="y">316</authenticatordata>  
  </WinAuthAuthenticator>


Wenn ich das Skript mehrfach ausgebe sieht das beispielsweise wie folgt aus:
(Max, Mira, Max, Mira und Karl ist nun auch dabei)

  <WinAuthAuthenticator id="be2ccecc18f1" type="WinAuth.GoogleAuthenticator">  
    <name>Max Mustermann</name>
    <created>1580897853024</created>
    <lastused>1580897940934</lastused>
    <autorefresh>false</autorefresh>
    <allowcopy>false</allowcopy>
    <copyoncode>false</copyoncode>
    <hideserial>false</hideserial>
    <skin>WinAuthIcon.png</skin>
    <authenticatordata encrypted="y">940C</authenticatordata>  
  </WinAuthAuthenticator>
  <WinAuthAuthenticator id="ff40d1b9d261" type="WinAuth.GoogleAuthenticator">  
    <name>Mira Musterfrau</name>
    <created>1580898599724</created>
    <lastused>1580898599724</lastused>
    <autorefresh>false</autorefresh>
    <allowcopy>false</allowcopy>
    <copyoncode>false</copyoncode>
    <hideserial>false</hideserial>
    <skin>WinAuthIcon.png</skin>
    <authenticatordata encrypted="y">316</authenticatordata>  
  </WinAuthAuthenticator>  <WinAuthAuthenticator id="be2ccecc18f1" type="WinAuth.GoogleAuthenticator">  
    <name>Max Mustermann</name>
    <created>1880897853024</created>
    <lastused>1880897940934</lastused>
    <autorefresh>false</autorefresh>
    <allowcopy>false</allowcopy>
    <copyoncode>false</copyoncode>
    <hideserial>false</hideserial>
    <skin>WinAuthIcon.png</skin>
    <authenticatordata encrypted="y">940C</authenticatordata>  
  </WinAuthAuthenticator>
  <WinAuthAuthenticator id="ff40d1b9d261" type="WinAuth.GoogleAuthenticator">  
    <name>Mira Musterfrau</name>
    <created>1980898599724</created>
    <lastused>1980898599724</lastused>
    <autorefresh>false</autorefresh>
    <allowcopy>false</allowcopy>
    <copyoncode>false</copyoncode>
    <hideserial>false</hideserial>
    <skin>WinAuthIcon.png</skin>
    <authenticatordata encrypted="y">316</authenticatordata>  
  </WinAuthAuthenticator>
  <WinAuthAuthenticator id="ff40d1b9d256" type="WinAuth.GoogleAuthenticator">  
    <name>Karl Musterkind</name>
    <created>1880998599724</created>
    <lastused>1880998599724</lastused>
    <autorefresh>false</autorefresh>
    <allowcopy>false</allowcopy>
    <copyoncode>false</copyoncode>
    <hideserial>false</hideserial>
    <skin>WinAuthIcon.png</skin>
    <authenticatordata encrypted="y">634</authenticatordata>  
  </WinAuthAuthenticator>


---
Nun muss noch Punkt 3 durchgeführt werden. Dabei benötige ich Unterstützung.
Die Doppelten Blöcke nach Namen erfassen und die ältesten löschen, so dass pro Person nur noch einer zurückbleibt.
Pro Block ein Array?
---
Das in eine Textdatei als Master.

Die Inhalte mit Kopf Master und Fußzeile würde ich dann Nachts zusammenfügen, so dass diese morgens als Ausgangs-XML den Personen zur Verfügung steht.

Vielen Dank für eure Hilfe!

Content-Key: 551803

Url: https://administrator.de/contentid/551803

Printed on: April 26, 2024 at 21:04 o'clock

Mitglied: 143127
143127 Feb 26, 2020 updated at 13:17:25 (UTC)
Goto Top
Anmerkungen dazu.
  • 1. XML Dateien bearbeitet man nicht als reinen Text sondern lässt sie durch einen Parser laufen und erstellt daraus ein Objekt um ungültigen Markup zu vermeiden. Dafür gibt es in VBS/VBA das Objekt "MSXML2.DomDocument" mit dem man die XML Struktur durchlaufen und Knoten und Attribute als Ganzes auswählen kann. Man siehe https://analystcave.com/vba-xml-working-xml-files/
  • 2. Würde ich bei parallelem Zugriff auf eine Datenbank-Speicherung mit Transaktionen / Locks ausweichen.
Member: worker0815
worker0815 Feb 27, 2020 at 15:28:03 (UTC)
Goto Top
Vielen Dank für die Unterstützung bzw. Anmerkung.
Ich habe es nun anders gelöst. Mit PowerShell:

Aufgabe 1:
#Alle 5 Minuten (06:00 - 21:00)
$xml = [xml](Get-Content -Path "\\localhost\APPS\Pfad\grpauth.xml")  

$xml.SelectNodes("//WinAuthAuthenticator") | %{  
    $name = $_.name + "_" + $_.created + ".xml"  
    "$($_.outerXML)" | set-content \\localhost\APPS\Pfad\Benutzer\$name  
}


Damit werden mir alle Blöcke mit eigenen Namen in das Verzeichnis Pfad\Benutzer abgelegt.
Zusätzlich habe ich 2 Textdateien mit Kopf- und Fußzeile, vor und nach den Blöcken.

Aufgabe 1:
#Alle 5 Minuten (21:00)
GetContent "\\localhost\APPS\Pfad\Master\Master_01_Anfang.txt", "\\localhost\APPS\Pfad\Benutzer\*.xml", "\\localhost\APPS\Pfad\Master\Master_03_Ende.txt" > grpauth.xml  


Damit füge ich Kopfzeile, alle Blöcke der Benutzer und die Fußzeile wieder zu einer Datei zusammen und habe meinen Master.

Das reicht mir.
Mitglied: 143127
143127 Feb 27, 2020 updated at 16:20:37 (UTC)
Goto Top
Ich habe es nun anders gelöst. Mit PowerShell:
Naja hätte man auch gleich erwähnen können das man schon mal mit der PS mal hantiert hat, dann hätten wir hier nicht mit dem alten VBS rumschnüffeln müssen face-wink.
Noch ein Hinweis zu der Zeile
$xml = [xml](Get-Content -Path "\\localhost\APPS\Pfad\grpauth.xml")
Man sollte die XML besser so laden
$xml = New-Object XML
$xml.Load("\\localhost\APPS\Pfad\grpauth.xml")  
Da ansonsten mit Get-Content nicht sichergestellt ist das das Encoding aus der XML korrekt verwendet wird sondern das Console Encoding bzw. das Encoding was Get-Content meint erkennen zu wollen! Wenn man das mit Get-Content lädt sollte man auch das Encoding entsprechend mit angeben.
Die Load-Methode dagegen berücksichtigt das Encoding das in der XML Declaration steht schon automatisch.