nexxudus
Goto Top

VBS Suchen und Ersetzen bei UTF8 XML Dateien funktioniert nicht

Hallo zusammen,
ich verzweifel gerade an einer - eigentlich total primitiven- Aufgabe.
Dazu muss ich sagen, dass ich mich mit VB nicht wirklich auskenne, wahrscheinlich übersehe ich daher einfach etwas.

Aufgabestellung:
Ich habe eine XML Datei im UTF8 Format.
Dort sind in einer Zeile mehrere Informationen, immer beginnent mit einem <row> und endet mit einem </row>
Das Programm, dass die Informationen dazwischen verarbeitet, kann diese aber nicht auslesen bzw gibt einen Fehler zurück, da
der Inhalt ohne das Beginnende <row> sein muss, kurz gesagt, ich möchte ein: Suche <row> und ersetze es durch nichts, Suche </row> und ersetzte es durch nichts. (Beides kann in der Datei öfter vorkommen)

Ich habe mich im Forum etwas durch gelesen und schon getestet, komme aber nicht auf die Lösung.
Ich dachte dieser einfache Befehl würde genügen:

Ein = "D:\Temp\Partlist.xml"
Aus = "D:Temp\Partlist_NEU.xml"
Set fso = CreateObject("Scripting.FileSystemObject")
Set rE = New RegExp
T = fso.OpenTextFile(Ein).ReadAll

rE.Pattern = "<row>"
T = rE.Replace (T, "")
rE.Pattern = "</row>"
T = rE.Replace (T, "")

fso.CreateTextFile(Aus).Write T

Laut Fehlermeldung wäre in der Letzten Zeile ein Ungültiger Prozedurablauf oder ungülstiges Argument.
Könnt ihr mir helfen? Ich verzweifel an so etwas einfachem face-sad(

Content-Key: 336751

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

Printed on: April 16, 2024 at 04:04 o'clock

Mitglied: 132895
132895 May 03, 2017 updated at 16:11:29 (UTC)
Goto Top
Hi.
XML-Dateien sollte man wenn möglich immer mit einem Parser bearbeiten, hier ein Beispiel für dein Vorhaben in VBS durch den das UTF-8 korrekt verarbeitet wird.
Const XMLFILE = "D:\daten.xml"  
Set xmldoc = CreateObject("msxml2.domdocument.6.0")  
xmldoc.async = False
xmldoc.load(XMLFILE)
Set nodes = xmldoc.selectNodes("//row")  
If Not nodes Is Nothing Then
	For Each node In nodes
		node.parentNode.removeChild node
	Next
    xmldoc.save XMLFILE
End If
set xmldoc = Nothing
oder als Powershell nach dem selben Schema:
$file = 'D:\daten.xml'  
$xml = New-Object XML
$xml.Load($file)
$xml.SelectNodes('//row') | %{$_.parentNode.RemoveChild($_)}  
$xml.Save($file)
Bitte beachten. Enthält dein XML-File "Namespaces" muss der Code angepasst werden, dafür müsstest du dann dein File hier posten!


Möchtest du wirklich manuell in einem UTF-8 XML File rumpfuschen, UTF-8 kodierten Text bekommst du mit diesen beiden Functions korrekt in dein VB(A/S) rein und auch korrekt wieder raus:
Sub WriteUTF8(file, text)
  With CreateObject("ADODB.Stream")  
  	.Type = 2
  	.Charset = "UTF-8"  
  	.Open
  	.WriteText text
  	.SaveToFile file, 2
  	.Close
  End With
End Sub

Function ReadUTF8(file)
    With CreateObject("ADODB.Stream")  
	.Type = 2
	.Charset = "UTF-8"  
	.Open
	.LoadFromFile(file)
	ReadUTF8 = .ReadText
	.Close
    End With
End Function

Gruß
Member: Nexxudus
Nexxudus May 03, 2017 at 17:30:30 (UTC)
Goto Top
Hi und vielen Dank für die Antwort. Na wenn es besser mit einem Parser ist dann nehme ich gerne diese Möglichkeit.
Habe direkt die erste Möglichkeit versucht, diese funktioniert auch, nur leider zu gut.

Jetzt passiert folgendes:
anstatt das er nur das <row> herausnimmt, nimmt er alles innerhalb des row Befehles heraus.
Eigentlich sollte dieser Text:

...hier etwas Text...
<row><Cono>010</Cono><Faci>GBB</Faci></row>
<row><Cono>010</Cono><Faci>DEB</Faci></row>
...hier etwas Text

Danach so aussehen:
<Cono>010</Cono><Faci>GBB</Faci>
<Cono>010</Cono><Faci>DEB</Faci>

Das Ergebnis aus dem oben genannten ist aber nur der Text zuvor.
Ich darf wirklich nur das row mehr oder weniger als String behandeln und den "String" <row> und </row> entfernen.

Gibt es da einen Trick?
Mitglied: 132895
132895 May 03, 2017, updated at May 04, 2017 at 06:22:42 (UTC)
Goto Top
Na dann verschiebt man vorher die ChildNodes der row-Elemente in den parentNode des row-Elements und löscht dann das nun leere row-Element:
Const XMLFILE = "D:\daten.xml"  
Set xmldoc = CreateObject("msxml2.domdocument.6.0")  
xmldoc.async = False
xmldoc.load(XMLFILE)
Set nodes = xmldoc.selectNodes("//row")  
If Not nodes Is Nothing Then
	For Each node In nodes
                for each subnode in node.childNodes
                    node.parentNode.insertBefore subnode,node
                Next
		node.parentNode.removeChild node
	Next
    xmldoc.save XMLFILE
End If
set xmldoc = Nothing
Member: Nexxudus
Nexxudus May 04, 2017 at 05:08:25 (UTC)
Goto Top
Hi password,
danke nochmal für deine Hilfe.
Habe deine Letzte Info nun so eingebaut,
beim ersten Durchlaufen hat er mir die Klammern in der Subnode angemeckert.
Wenn ich die Klammern hier entferne: node.parentNode.insertBefore subnode,node
läuft es zwar durch, das File ist danach aber komplett leer.

*verzweifelt ist*
Mitglied: 132895
Solution 132895 May 04, 2017 updated at 07:27:51 (UTC)
Goto Top
eim ersten Durchlaufen hat er mir die Klammern in der Subnode angemeckert.
Gut das war ein Tippfehler, ist korrigiert.
läuft es zwar durch, das File ist danach aber komplett leer.
Nein es funktioniert definitiv, wurde hier mehrfach mit unterschiedlichsten Nodes einwandfrei getestet!
Der Fehler liegt also bei dir.

back-to-topOriginal:
screenshot

back-to-topNach dem Skript:
screenshot
Member: Nexxudus
Nexxudus May 04, 2017 at 13:00:31 (UTC)
Goto Top
Es funktioniert...vielen vielen Dank.

Das Script hat nach dem herausnehmen der Klammern direkt funktioniert, ich hatte mich selbst verarscht.
Hatte es zum Testen von etwas anderem nach UTF16 konvertiert, dann deine Funktion getestet und das File war immer leer.
Wenn das Format in UTF-8 ist funktioniert es.
Super, hat mir sehr geholfen.
Mitglied: 132895
132895 May 04, 2017 updated at 13:19:14 (UTC)
Goto Top
War zu erwarten face-smile
Hatte es zum Testen von etwas anderem nach UTF16 konvertiert
Das kann ja nicht funktionieren wenn in der XML-Declaration UTF-8 steht face-wink

Gruß