PDA

Vollständige Version anzeigen : xml mit Dateiheader auslesen


Watzke41
02.06.2012, 10:45
Hallo Gemeinde,

ich möchte neben dem xml Inhalt auch den Header der Datei auslesen und in einer Tabelle speichern. Habe hier ein Muster der Datei, und der Importschleife
Vielleicht habt ihr eine Lösung??
Speziell geht es um diese Daten: LicenseOwnerName="G. Mustermann" UploadDate="31.05.12"

Danke erstmal

hier die Schleife:

Private Sub Befehl69_Click()

Dim AktDatNam As String, DatDatum As Date, sSQL As String

AktDatNam = Dir("P:\Import\" & "*.xml")
While AktDatNam <> ""
Application.ImportXML "P:\Import\" & AktDatNam, acAppendData
DatDatum = FileDateTime("P:\Import\" & AktDatNam)
sSQL = "UPDATE Page SET DateiName = '" & AktDatNam & "', "
sSQL = sSQL & "DateiDatum = '" & DatDatum & "' "
sSQL = sSQL & "WHERE DateiName Is Null"
Debug.Print sSQL ' ^G Direktfenster
CurrentDb.Execute sSQL, 128
AktDatNam = Dir
Wend
End Sub

hier die xml Struktur: (<> sind entfernt)


?xml version="1.0" encoding="utf-8" standalone="yes" ?
- Project LicenseOwnerName="G. Mustermann" UploadDate="31.05.12" UploadTime="23:30:16" ProjectName="Arbeitsnachweis" ProjectId="37734391-96d2-4684-9c8b-91bdfc371413" ExportDate="31.05.2012" ExportTime="23:34:19"
- Pages
- Page PageName="21.2443.6.86"
ArtderArbeit>1</ArtderArbeit
AS_Text>Wartung laut Arbeitskarte</AS_Text
AttachmentNameTemplate /
AuftrNr>0</AuftrNr
drawingarea_0 /
FabrNr>11006</FabrNr
Monteur>Mitte</Monteur
AsNr>0016634</AsNr
Ort>XX</Ort
Standort>UD Haus 27 </Standort
/Page
/Pages
/Project"

ebs17
02.06.2012, 12:51
Du könntest einfache Textverarbeitung verwenden, um diese Informationen herauszulesen: Datei in Stringvariable einlesen, Stringvariable per RegEx (http://www.ms-office-forum.net/forum/showthread.php?t=256917) analysieren oder per Split in Zeilen zerlegen und dann die gewünschte Zeile parsen. Beispiel:
Dim vArr As Variant
' ...

' in der Schleife
' ReadFile aus http://vb-tec.de/readfile.htm
' um zweite Zeile zu analysieren
vArr = Split(ReadFile("P:\Import\" & AktDatNam), vbCrLf, 3)
Debug.Print vArr(1)
' Verarbeitung des Zeileninhaltes

Watzke41
03.06.2012, 14:29
Hallo Eberhardt,
danke für deinen Vorschlag. Ich werde nächste Woche daran basteln und mich dann sicher noch mal melden.
Schönen Sonntag
Gruß Thomas

Marsu65
03.06.2012, 16:53
Hallo zusammen,

wenn es nur um die beiden Werte LicenseOwnerName und UploadDate geht, lässt sich das rel. leicht über Das XML-DOM auslesen.
Bsp:http://ms-office-forum.net/forum/showthread.php?t=289146

Wenn du eine echte Datei hier anhängst, kann man schnell was "basteln".

BTW: wenn du den Dateiinhalt in PHP-Tags packst, kannst du ihn hier auch mit <> posten (wäre einfacher zu lesen).

Watzke41
07.06.2012, 17:55
Hallo Ihr zwei,
habe ein wenig mit euren Vorschlägen probiert, komme aber zu keinem Ergebnis! Da fehlen bei mir doch die Grundlagen von VBA! Mit RegEX komme ich gar nicht klar! Mit dem Vorschlag von Marsu habe ich den selben Import wie in meiner alten Schleife. Excel passt den Import der Struktur der Datei an und gibt sie vollständig aus, nur access ist etwas komplizierter. Habe eine Originaldatei mal im Zip angehängt. (Ich hoffe es funktioniert) Vielleicht habt ihr für meinen Import noch eine relativ einfache Lösung.

Danke Im Voraus
Thomas

Marsu65
07.06.2012, 18:44
Hallo Thomas,
ist tatsächlich immer nur ein Datensatz bezgl.
LicenseOwner und UploadDate in den Dateien vorhanden?
Und du brauchst wirklich nur die beiden Felder?

Watzke41
07.06.2012, 18:54
Danke für die Nachfrage,
ich benötige natürlich auch die Felder aus der gesamten Datei, die bringt mir aber jede Importschleife (siehe 1.Meldung, oder auch dein Beispiel) Die Kopfdaten werden aber nicht mit ausgelesen, davon brauche ich aber nur die beiden Informationen)
gruß
Thomas

Marsu65
07.06.2012, 19:09
Jepp, gerade gesehen, dass du per ImportXML importierst.
Da fehlen alle Attribute.

PageName dürfte somit auch nicht in deinem Import enthalten sein.
Brauchst du das Feld auch (<Strike>sowie die anderen Atribute: UploadTime, ProjectName, ...</strike>)?

Marsu65
07.06.2012, 19:44
Hier eine kleine Sub, mit der du die beiden Werte auslesen kannst:
Sub GetXMLHeader(ByVal FilePathName As String, ByRef LON As String, ByRef UploadDate As String)
Dim xDoc As MSXML2.DOMDocument
Dim xNodelist As MSXML2.IXMLDOMNodeList
Set xDoc = New MSXML2.DOMDocument
'xml vorbereiten und einlesen
With xDoc
.async = False
.preserveWhiteSpace = False
.validateOnParse = True
.resolveExternals = False
.Load FilePathName
End With
'Aufzaehlung mit allen Knoten die Project heissen
Set xNodelist = xDoc.getElementsByTagName("Project")
'Auslesen der ersten beiden Attributwerte
LON = xNodelist(0).Attributes(0).Text
UploadDate = xNodelist(0).Attributes(1).Text
'Debug.Print LON, UploadDate
Set xNodelist = Nothing
Set xDoc = Nothing
End Sub

Aufzurufen z.B. mit
Dim LON As String, UploadDate As String
...
Call GetXMLHeader(f, LON, UploadDate)
'LON und UploadDate werde referenziert übergeben und können hier weiter "verwertet" werden.
...
'... Mach was mit LON und UploadDate


VERWEIS auf MIcrosoft XML, v6.0 (msxml6.dll) muss gesetzt sein!

Watzke41
07.06.2012, 19:45
Hallo Marsu
sorry, also ich brauche den xmlImport, die beiden Felder aus dem Kopf und den Dateinamen alles ander ist Nebensache.

Danke

Marsu65
07.06.2012, 19:59
Dann hast du ja jetzt alles zusammen, oder ist noch was offen?

Watzke41
09.06.2012, 09:16
Hallo Marsu,
danke für deine Bemühungen! Den Code versuche ich zu verstehen. Da ich aber mich erst seit kurzem mit VBA beschäftige, fehlt mir jetzt die Verknüpfung zu meinen Ordnern, Tabellen.
_LON und UploadDate werde referenziert übergeben_ - dieser Hinweis bringt mich auch nicht weiter, sorry eben Anfänger. Vieleicht kannst du die Zuweisungen etwas genauer Beschreiben.
Danke schon mal.
Gruß Thomas

Marsu65
09.06.2012, 15:36
Hallo,

du kopierst die Sub in dein (Formular-)Modul und könntest deine eigene
Prozedur z.B. wie folgt erweitern:
Private Sub Befehl69_Click()

Dim AktDatNam As String, DatDatum As Date, sSQL As String
Dim LON As String, UploadDate As String

AktDatNam = Dir("P:\Import\" & "*.xml")

While AktDatNam <> ""
Application.ImportXML "P:\Import\" & AktDatNam, acAppendData
DatDatum = FileDateTime("P:\Import\" & AktDatNam)

Call GetXMLHeader(AktDatNam, LON, UploadDate)

sSQL = "UPDATE Page SET DateiName = '" & AktDatNam & "', "

sSQL = sSQL & "[LicenceOwnerName] = '" & LON & "', "
sSQL = sSQL & "[UploadDate] = '" & UploadDate & "', "

sSQL = sSQL & "DateiDatum = '" & DatDatum & "' "
sSQL = sSQL & "WHERE DateiName Is Null"
Debug.Print sSQL ' ^G Direktfenster
CurrentDb.Execute sSQL, 128
AktDatNam = Dir
Wend
End Sub


Die neuen/veränderten Zeilen sind grün makiert.

Die Feldnamen [LicenceOwnerName] und [UploadDate] musst du an die von dir verwendeten Feldnamen in der Tabelle Page anpassen.
Ich bin davon ausgegangen, dass beide Felder vom Datentyp Text sind.
Sollte z.B. UploadDate vom Typ Datum/Uhrzeit sein, muss das in der SQL-Anweisung noch berücksichtigt werden.

Denke daran den Verweis zu setzen!

Watzke41
10.06.2012, 21:28
Hallo Marsus,
danke für deine Antworten, langsam wird es eine runde Sache. Aber eben noch mit kleinen Problemen. Ich bekomme jetzt die Fehlermeldung:
-objektvariable oder with-blockvariable nicht festgelegt-
der Code bleibt im Modul in der Zeile stehen:
-LON = xNodelist(0).Attributes(0).Text-
Wenn du hier noch einen Plan hättest, dann läuft der Code bestimmt durch!

Danke schon mal für deine Geduld!
Gruß Thomas

Marsu65
10.06.2012, 21:42
Kann es sein, dass die Datei, die in der Prozedur verarbeitet wird, keinen Eintrag (Attribut) LicenceOwnerName hat?

Das Konstrukt reagiert sehr sensibel auf Unterschiede im Aufbau deiner xml-Dateien.

Ganz allgemein könnte man solche Fehler durch eine geeignete Fehlerbehandlung abfangen.
Zuerst sollte jedoch die Analyse stehen, warum es zu dem Fehler kommt.

Watzke41
11.06.2012, 09:47
habe jetzt nochmal alles kontrolliert,
habe auch einen Schreibfehler gefunden,
trotzdem bleiben die Felder leer und der import bricht ab, selbe Meldung!
ich habe dir das lokalfenster mal angehangen und ein Dateikopf. Vielleicht siehst du daran das Problem??

Gruß Thomas


Dateihaeder
[?xml version="1.0" encoding="utf-8" standalone="yes"?>
[Project LicenseOwnerName="J. Liebing" UploadDate="09.06.12" UploadTime="04:27:56" ProjectName="Arbeitsnachweis" ProjectId="[37734391-96d2-4684-9c8b-91bdfc371413" ExportDate="09.06.2012" ExportTime="06:29:31">
[Pages>
[Page PageName="21.2443.6.86">]
Lokalfenster im Anhang - jetzt mit Anhang!

ebs17
11.06.2012, 11:24
Mit RegEX komme ich gar nicht klar!
Nur zur Vervollständigung:
Private Sub Befehl69_Click()

Dim AktDatNam As String, DatDatum As Date, sSQL As String
Dim db As DAO.Database
Dim oCol As Object
Dim sPattern As String
Set db = CurrentDb
sPattern = "Project LicenseOwnerName=" & Chr(34) & "([\w| |\.]+)" & Chr(34) & _
" UploadDate=" & Chr(34) & "(\d{2}\.\d{2}\.\d{2})"""

AktDatNam = Dir("P:\Import\" & "*.xml")

While AktDatNam > vbNullString
Application.ImportXML "P:\Import\" & AktDatNam, acAppendData
DatDatum = FileDateTime("P:\Import\" & AktDatNam)

Set oCol = RegExMatchCollection(ReadFile("P:\Import\" & AktDatNam), sPattern)
If oCol.Count > 0 Then
' Debug.Print oCol(0).SubMatches(0)
' Debug.Print oCol(0).SubMatches(1)

sSQL = "UPDATE Page SET DateiName = '" & AktDatNam & "', "

sSQL = sSQL & "[LicenceOwnerName] = '" & oCol(0).SubMatches(0) & "', "
sSQL = sSQL & "[UploadDate] = " & CLng(DateValue(oCol(0).SubMatches(1))) & ", "

sSQL = sSQL & "DateiDatum = " & Str(CDbl(DatDatum)) & " "
sSQL = sSQL & "WHERE DateiName Is Null"
Debug.Print sSQL
db.Execute sSQL, dbFailOnError
Else
MsgBox "Headerinformationen in Datei " & AktDatNam & " nicht gefunden. Abbruch!"
Exit Sub
End If
AktDatNam = Dir
Wend
Set oCol = Nothing
Set db = Nothing
End Sub

' in Standardmodul

Private pRegEx As Object

Public Property Get oRegEx(Optional Reset As Boolean) As Object
If (pRegEx Is Nothing) Then Set pRegEx = CreateObject("Vbscript.Regexp")
If Reset Then Set pRegEx = Nothing
Set oRegEx = pRegEx
End Property

Public Function RegExMatchCollection(ByVal SourceText As String, _
ByVal SearchPattern As String, _
Optional ByVal bIgnoreCase As Boolean = True, _
Optional ByVal bGlobal As Boolean = True, _
Optional ByVal bMultiLine As Boolean = True) As Object

With oRegEx
.Pattern = SearchPattern
.IgnoreCase = bIgnoreCase
.Global = bGlobal
.Multiline = bMultiLine
Set RegExMatchCollection = .Execute(SourceText)
End With
End Function

Public Function ReadFile(ByRef Path As String) As String
Dim FileNr As Long

'Falls nicht vorhanden, nichts zurückgeben:
On Error Resume Next
If FileLen(Path) = 0 Then Exit Function
On Error GoTo 0

'Datei einlesen:
FileNr = FreeFile
Open Path For Binary As #FileNr
ReadFile = Space$(LOF(FileNr))
Get #FileNr, , ReadFile
Close #FileNr
End Function

Watzke41
11.06.2012, 13:26
Hallo Eberhardt,
danke dass du dich auch nochmal mit diesem Thema beschäftigst. Werde es mal auf diese Weise probieren.
Mal sehen ob es klappt!
Gibt es hier noch eine Erläuterung nach welchem Schema die Zeichen gesetzt sind?? -für mich spanische Dörfer!

sPattern = "Project LicenseOwnerName=" & Chr(34) & "([\w| |\.]+)" & Chr(34) & _
" UploadDate=" & Chr(34) & "(\d{2}\.\d{2}\.\d{2})"""

Danke
Thomas

ebs17
11.06.2012, 14:08
Der Ausdruck an sich sollte Dir aus Deiner XML-Datei bekannt vorkommen.
Durch die Darstellung in VBA muss aber das Doublequote aus dem String ausgelagert werden (=> Chr(34)), weil es sonst den String "zerreißt". Die auch mögliche Verdopplung des Doublequotes habe ich nur am Ende verwendet.

Innerhalb dieses Suchmusters sind die gesuchten Zeichenfolgen mit runden Klammern umschlossen und so als Untersuchmuster (Subpattern) identifizierbar.

([\w| |\.]+)
\w ... Schriftzeichen (Buchstabe ohne Umlaute oder Ziffer oder Unterstrich)
\. ... Punkt (muss mit Backslash maskiert werden, weil der Punkt sonst beliebige Zeichen darstellt)

Also Schriftzeichen oder Leerzeichen oder Punkt, und das mindestens einmal. Der Gesamtausdruck dann innerhalb der genannten Doublequotes an der entsprechenden Stelle im gesamten Suchmuster.
Wenn bei den Bezeichnungen noch weitere Zeichen auftreten könnten (vgl. Datenbasis) wie z.B. ein Apostroph o.a., müsste dann das Subpattern dahingehend ergänzt werden.

(\d{2}\.\d{2}\.\d{2})
=> Zeichenfolge 2 Ziffern, Punkt, 2 Ziffern, Punkt, 2 Ziffern

Siehe auch "Intelligente" Textanalyse (http://www.ms-office-forum.net/forum/showthread.php?t=256917).

Eberhardt
Als Sachse würde ich sagen: Am Ende bitte nur ein weiches "d".

Marsu65
11.06.2012, 14:43
Hallo Thomas,
die Variable FilePathName enthält nur den Dateinamen.
Hier muss der vollständige Pfad übergeben werden.
Ändere
Call GetXMLHeader(AktDatNam, LON, UploadDate)
in
Call GetXMLHeader("P:\Import\" & AktDatNam, LON, UploadDate)

Watzke41
29.06.2012, 20:56
Hallo Marsus, hallo Eberhardt,

bei dem vielen Fußball ist die Datenbank zu kurz gekommen!
Ich habe mich aber trotzdem fleißig mit dem Thema beschäftigt und habe nun zwei gehende Varianten.
Danke euch beiden, und wie so oft: Der Fehler sitzt vor dem Gerät!
Man muss eben jedes Komma und Hochkomma beachten! Ein Feld war auch falsch bezeichnet.
Danke nochmal, bis zum nächsten mal!

Watzke41
29.06.2012, 20:59
der Dank fehlt noch....
Hallo Marsus, hallo Eberhardt,

bei dem vielen Fußball ist die Datenbank zu kurz gekommen!
Ich habe mich aber trotzdem fleißig mit dem Thema beschäftigt und habe nun zwei gehende Varianten.
Danke euch beiden, und wie so oft: Der Fehler sitzt vor dem Gerät!
Man muss eben jedes Komma und Hochkomma beachten! Ein Feld war auch falsch bezeichnet.
Danke nochmal, bis zum nächsten mal!