Announcement

Collapse
No announcement yet.

Inhalt einer XML Datei in Abhängigkeit der Attributswerte auslesen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Inhalt einer XML Datei in Abhängigkeit der Attributswerte auslesen

    Ich möchte die Daten einer XML Datei nach Access 2000 importieren.
    Wenn in der XML Datei die Werte "alleine stehen" (<Element>INHALT</Element>), dann ist es kein Problem "INHALT" einer Variable zuzuweisen.
    Wenn die XML Struktur so aussieht: "<metatag name="heigth" type="System.Int32">2557</metatag>" und sich diese Struktur mit abwechselnden Namen (name="alignment", name="heigth", name="width" etc.) wiederholt, weiß ich nicht, wie ich NUR "heigth" ansprechen kann. Ich will praktisch sagen: Wenn Programmcode bei <metatags> angekommen ist, dann suche nach "heigth" und schreibe dessen Wert (und keinen anderen) in die Variable.

    Würde mich freuen, wenn Ihr mir helfen könnt - Danke im Voraus!

    Gruß
    J.R.

    Inhalt des XML Files (test.xml) - Ausschnitt, um den es letztendlich geht:
    Code:
    <?xml version="1.0" encoding="utf-16" ?> 
    <metatags>
      <metatag name="alignment" type="System.String">H</metatag> 
      <metatag name="posX" type="System.Int32">635</metatag> 
      <metatag name="posY" type="System.Int32">438</metatag> 
      <metatag name="heigth" type="System.Int32">2559</metatag> 
      <metatag name="width" type="System.Int32">1275</metatag> 
      <metatag name="pageWidth" type="System.Int32">2480</metatag> 
      <metatag name="pageHeigth" type="System.Int32">3520</metatag> 
      <metatag name="fullpage" type="System.Int32">1</metatag> 
      <metatag name="ID_SES_Medienblatt" type="System.Int32">17818167</metatag> 
      </metatags>
    VBA-Code
    Code:
    Option Compare Database
    Option Explicit
    Public XYZ As Recordset
    Public DeBe As Database
    Public StatusOffen
    Public medienblattID
    Public PdF
    Public ThemenId
    Public FirstEntry
    Public tk
    Public mtheigth As Integer
    Public mtwidth As Integer
    Public sthoehe As Integer
    Public stbreite As Integer
    Public preis_1c As Single
    Public objNode As MSXML2.IXMLDOMNode
    
    Private Sub Befehl30_Click()
    On Error GoTo Err_Befehl30_Click
       Dim objDoc As DOMDocument
       Dim dateiname As String
       dateiname = "S:\XYZ\test.xml"
       If Not L_fileexist(dateiname) Then
          MsgBox "Keine Datei " & dateiname & " vorhanden", vbCritical, "Hinweis"
          Exit Sub
       End If
       Set objDoc = CreateObject("MSXML2.DOMDocument")
       objDoc.Load dateiname  ' XML-Document laden
       StatusOffen = False
       FirstEntry = True
       Call GetChildNodes(nodeList:=objDoc.childNodes)
    End Sub
    ‘/////
    Public Sub GetChildNodes(ByVal nodeList As MSXML2.IXMLDOMNodeList)
    On Error GoTo Err_GetChildNodes_Click
        For Each objNode In nodeList
            If objNode.hasChildNodes = True Then
                If objNode.nodeName = "Meldung" Then
                    If StatusOffen Then
                        XYZ!Medienblatt_ID = medienblattID
                        XYZ!pdf_name = PdF
                        XYZ!headline = headline
                        XYZ!ZYX_thema_id = ThemenId
                        XYZ!ursprungsthema = ThemenId
                        XYZ!einlesedatum = Date
                        XYZ!Textkuerzel = tk
                        XYZ.Update
                        XYZ.Close
                        Set XYZ = Nothing
                        Set DeBe = Nothing
                        If Not IsNull(ThemenId) Then
                            DoCmd.SetWarnings False
                            DoCmd.RunSQL ("UPDATE XYZ SET XYZ.ZYX_thema_id = ThemenId, XYZ.ursprungsthema = ThemenId WHERE (((XYZ.Medienblatt_ID)=[medienblattID]))")
                            DoCmd.SetWarnings True
                            ThemenId = Null
                        End If
                        StatusOffen = False
                    Else
                        If FirstEntry Then
                            FirstEntry = False
                        Else
                            Set DeBe = CurrentDb
                            Set XYZ = DeBe.OpenRecordset("XYZ", dbOpenDynaset, dbSeeChanges)
                            XYZ.AddNew
                            medienblattID = Null
                            PdF = Null
                            headline = Null
                            ThemenId = Null
                            tk = Null
                            StatusOffen = True
                        End If
                    End If
                End If
               If objNode.nodeName = "Erscheinen" Then
                  If StatusOffen Then
                     XYZ!Medienblatt_ID = medienblattID
                     XYZ!pdf_name = PdF
                     XYZ!headline = headline
                     XYZ!ZYX_thema_id = ThemenId
                     XYZ!ursprungsthema = ThemenId
                     XYZ!einlesedatum = Date
                     XYZ!Textkuerzel = tk
                     XYZ.Update
                     XYZ.Close
                     Set XYZ = Nothing
                     Set DeBe = Nothing
                     Set DeBe = CurrentDb
                     Set XYZ = DeBe.OpenRecordset("XYZ", dbOpenDynaset, dbSeeChanges)
                     XYZ.AddNew
                     StatusOffen = True
                  Else
                     Set DeBe = CurrentDb
                     Set XYZ = DeBe.OpenRecordset("XYZ", dbOpenDynaset, dbSeeChanges)
                     XYZ.AddNew
                     StatusOffen = True
                  End If
                End If
                Call GetChildNodes(nodeList:=objNode.childNodes)
            Else
                Select Case objNode.parentNode.nodeName
                    Case "ID_Medienblatt"
                        medienblattID = objNode.nodeTypedValue
                    Case "ID"
                        XYZ!XYZ_medien_ID = objNode.nodeTypedValue
                    Case "metatag"  
    ' in diesem Case heigth und width in Variable mtheigth/mtwidth einlesen
                    Case "Hoehe"
                        sthoehe = objNode.nodeTypedValue
                    Case "Breite"
                        stbreite = objNode.nodeTypedValue
                End Select
            End If
        Next objNode
    End Sub

  • #2
    Mit MSXML 3 oder 4 oder 5 oder 6 kann man XPath 1.0 verwenden:
    Code:
    Dim doc
    Set doc = CreateObject("Msxml2.DOMDocument.3.0")
    doc.setProperty "SelectionLanguage", "XPath"
    doc.async = False
    doc.load "datei.xml"
    Dim meta
    Set meta = doc.selectSingleNode("/metatags/metatag[@name = 'heigth']")
    If Not(meta Is Nothing) Then
      WScript.Echo meta.text
    Else
      WScript.Echo "nicht gefunden"
    End If
    Beachte, das "heigth" in deinem XML falsch geschrieben ist, richtig ist "height". Ich habe die falsche Schreibweise entsprechend auch im XPath-Ausdruck benutzt, damit Programmcode und Daten "passen", aber wenn kein Knoten gefunden wird, dann prüfe noch mal, ob eventuell in den Daten "height" statt "heigth" steht und ändere den XPath-Ausdruck entsprechend.

    Comment


    • #3
      Danke Martin Honnen,

      ich habs ausprobiert.
      Funktioniert nicht (liegt wahrscheinlich daran, dass ich nicht das ganze XML gepostet habe) - er gibt immer nur den higth Wert (2557) vom ersten Block metatags aus (siehe XML Dokument Inhalt weiter unten).
      Desweiteren: Beachte Bitte die Cases. Der Code zum "holen" des Elements metatag mit dem Attribut width/heigth soll in

      Code:
      Case "metatag"  
      ' in diesem Case heigth und width in Variable mtheigth/mtwidth einlesen
      ausgeführt werden (9. Zeile von unten im VBA Code des ersten Postings).

      Am einfachsten wäre es (rein von der menschlichen Logik im Bezug zum Code her), wenn ich anstatt
      Code:
      Case "metatag"
      sowas hier basteln könnte (frisst der Compiler aber nicht)
      Code:
      Case "metatag /metatags/metatag[@name = 'heigth']"" 
      'nach dem Motto: geh nicht in metatag rein und suche dann nach name="width"bzw."heigth" sondern geh direkt zu "width"/"heigth" in metatag.
      Verstehst du was ich meine?

      Gruß
      J.R.

      PS: Mir ist bewusst, dass "heigth" falsch geschrieben ist - ich habe das XML nicht geschrieben. Trotzdem danke für den Hinweis und entsprechende Beachtung.

      Hier der Inhalt des XML Files:
      Code:
      <?xml version="1.0" encoding="utf-16" ?>
       <XYZMedia xmlns="http://www.XYZMedia.de/schemas/export-meldungs-liste/1.0">
       <Meldung Medientyp="PRINT" ID_SES_Treffertyp="100">
       <Auftrag AccountId="30" Auftragsnummer="15013" Kundennummer="11073" Beschreibung="XYZ">
        <Suchbegriff ID="11386" Name="XYZFirma" />
        </Auftrag>
        <ID_Medienblatt>17818167</ID_Medienblatt>
       <Files>
        <PDF>17818167.pdf</PDF>
        </Files>
       <Inhalt>
       <Artikeltext>
       <data>
       <text>
       <image>
        <type>Picture</type>
        <filename>9e325850b330473896256af4d1aff81c.jpg</filename>
       <metatags>
        <metatag name="alignment" type="System.String">H</metatag>
        <metatag name="posX" type="System.Int32">309</metatag>
        <metatag name="posY" type="System.Int32">798</metatag>
        <metatag name="heigth" type="System.Int32">2557</metatag>
        <metatag name="width" type="System.Int32">2042</metatag>
        <metatag name="pageWidth" type="System.Int32">2480</metatag>
        <metatag name="pageHeigth" type="System.Int32">3520</metatag>
        <metatag name="fullpage" type="System.Int32">0</metatag>
        <metatag name="ID_SES_Medienblatt" type="System.Int32">17818167</metatag>
        </metatags>
        </image>
       <image>
        <type>Picture</type>
        <filename>c514946b99e94dc881aba4c3f0dbff25.jpg</filename>
       <metatags>
        <metatag name="alignment" type="System.String">H</metatag>
        <metatag name="posX" type="System.Int32">635</metatag>
        <metatag name="posY" type="System.Int32">438</metatag>
        <metatag name="heigth" type="System.Int32">2559</metatag>
        <metatag name="width" type="System.Int32">1275</metatag>
        <metatag name="pageWidth" type="System.Int32">2480</metatag>
        <metatag name="pageHeigth" type="System.Int32">3520</metatag>
        <metatag name="fullpage" type="System.Int32">1</metatag>
        <metatag name="ID_SES_Medienblatt" type="System.Int32">17818167</metatag>
        </metatags>
        </image>
       <image>
        <type>Picture</type>
        <filename>30fcbcb387f441c9b8a2538a22eebf01.jpg</filename>
       <metatags>
        <metatag name="alignment" type="System.String">H</metatag>
        <metatag name="posX" type="System.Int32">351</metatag>
        <metatag name="posY" type="System.Int32">500</metatag>
        <metatag name="heigth" type="System.Int32">2591</metatag>
        <metatag name="width" type="System.Int32">1837</metatag>
        <metatag name="pageWidth" type="System.Int32">2480</metatag>
        <metatag name="pageHeigth" type="System.Int32">3520</metatag>
        <metatag name="fullpage" type="System.Int32">1</metatag>
        <metatag name="ID_SES_Medienblatt" type="System.Int32">17818167</metatag>
        </metatags>
        </image>
       <image>
        <type>Picture</type>
        <filename>8852db3b302e494c909b325860a75b23.jpg</filename>
       <metatags>
        <metatag name="alignment" type="System.String">H</metatag>
        <metatag name="posX" type="System.Int32">523</metatag>
        <metatag name="posY" type="System.Int32">559</metatag>
        <metatag name="heigth" type="System.Int32">2516</metatag>
        <metatag name="width" type="System.Int32">1511</metatag>
        <metatag name="pageWidth" type="System.Int32">2480</metatag>
        <metatag name="pageHeigth" type="System.Int32">3520</metatag>
        <metatag name="fullpage" type="System.Int32">1</metatag>
        <metatag name="ID_SES_Medienblatt" type="System.Int32">17818167</metatag>
        </metatags>
        </image>
        </text>
        </data>
        </Artikeltext>
        </Inhalt>
       <Erscheinen>
       <Publikation>
       <Werbepreise>
        <Preis_1c>100</Preis_1c>
        <Preis_2c>200</Preis_2c>
        <Preis_3c>300</Preis_3c>
        <Preis_4c>400</Preis_4c>
        </Werbepreise>
       <Satz>
        <Hoehe>282</Hoehe>
        <Breite>2102</Breite>
        </Satz>
        </Publikation>
        </Erscheinen>
        </Meldung>
       <Meldung Medientyp="PRINT" ID_SES_Treffertyp="100">
       <Auftrag AccountId="30" Auftragsnummer="15013" Kundennummer="11073" Beschreibung="XYZ">
        <Suchbegriff ID="11386" Name="XYZFirma" />
        </Auftrag>
        <ID_Medienblatt>17819226</ID_Medienblatt>
       <Files>
        <PDF>17819226.pdf</PDF>
        </Files>
       <Inhalt>
       <Artikeltext>
       <data>
       <text>
       <image>
        <type>Picture</type>
        <filename>47dfae71998745ff8c0ca1ea15f7ed7c.jpg</filename>
       <metatags>
        <metatag name="alignment" type="System.String">V</metatag>
        <metatag name="posX" type="System.Int32">321</metatag>
        <metatag name="posY" type="System.Int32">1012</metatag>
        <metatag name="heigth" type="System.Int32">1542</metatag>
        <metatag name="width" type="System.Int32">2137</metatag>
        <metatag name="pageWidth" type="System.Int32">2480</metatag>
        <metatag name="pageHeigth" type="System.Int32">3520</metatag>
        <metatag name="fullpage" type="System.Int32">0</metatag>
        <metatag name="ID_SES_Medienblatt" type="System.Int32">17819226</metatag>
        </metatags>
        </image>
       <image>
        <type>Picture</type>
        <filename>4a523e87f0de4ad4a42d32ba7901ba90.jpg</filename>
       <metatags>
        <metatag name="alignment" type="System.String">V</metatag>
        <metatag name="posX" type="System.Int32">735</metatag>
        <metatag name="posY" type="System.Int32">1061</metatag>
        <metatag name="heigth" type="System.Int32">1389</metatag>
        <metatag name="width" type="System.Int32">973</metatag>
        <metatag name="pageWidth" type="System.Int32">2480</metatag>
        <metatag name="pageHeigth" type="System.Int32">3520</metatag>
        <metatag name="fullpage" type="System.Int32">1</metatag>
        <metatag name="ID_SES_Medienblatt" type="System.Int32">17819226</metatag>
        </metatags>
        </image>
        </text>
        </data>
        </Artikeltext>
        </Inhalt>
       <Erscheinen>
       <Publikation>
       <Werbepreise>
        <Preis_1c>150</Preis_1c>
        <Preis_2c>250</Preis_2c>
        <Preis_3c>350</Preis_3c>
        <Preis_4c>450</Preis_4c>
        </Werbepreise>
       <Satz>
        <Hoehe>270</Hoehe>
        <Breite>190</Breite>
        </Satz>
        </Publikation>
        </Erscheinen>
        </Meldung>
        </XYZMedia>
      Zuletzt editiert von JonesRidder; 18.01.2011, 17:14. Reason: Diese Version beachten - alle anderen sind überfällig

      Comment


      • #4
        Der Beispiel-Code sollte in erster Linie zeigen, wie man mit MSXML und selectSingleNode und XPath Knoten selektieren kann, ohne sich durch irgendwelche childNodes zu hangeln und dann den nodeName zu prüfen. Es gibt auch eine Methode selectNodes, mit der man eine Knotenliste selektieren kann, also etwa:
        Code:
        Dim doc
        Set doc = CreateObject("Msxml2.DOMDocument.3.0")
        doc.setProperty "SelectionLanguage", "XPath"
        doc.async = False
        doc.load "input.xml"
        doc.setProperty "SelectionNamespaces", "xmlns:df='" & doc.documentElement.namespaceURI & "'"
        Dim img
        For Each img In doc.selectNodes("//df:image")
          WScript.Echo img.selectSingleNode("df:type").text
          WScript.Echo img.selectSingleNode("df:filename").text
          WScript.Echo img.selectSingleNode("df:metatags/df:metatag[@name = 'heigth']").text
          WScript.Echo img.selectSingleNode("df:metatags/df:metatag[@name = 'width']").text
          WScript.Echo ""
        Next
        So würde ich das angehen, wenn ich mit MSXML Daten auslesen will. Das lässt sich jetzt nicht direkt in deine Funktion einfügen, aber ich bin leider nicht in der Lage, den VBA-Code zu lesen und zu verstehen, welche Elemente genau ausgelesen werden sollen.
        Wenn du nur dieses eine Case ändern willst, dann eventuell (so SelectionNamespaces bereits wie oben gesetzt ist):
        Code:
          mtheight = objNode.parentNode.parentNode.selectSingleNode("df:metatag[@name = 'heigth']").text
          mtwidth = objNode.parentNode.parentNode.selectSingleNode("df:metatag[@name = 'width']").text

        Comment


        • #5
          Ich danke dir für deine Hilfe.

          im Case, wo ursprünglich "metatag" stand steht jetzt folgendes:

          Code:
          Case "image"
          objDoc.setProperty "SelectionLanguage", "XPath"
          objDoc.async = False
          objDoc.setProperty "SelectionNamespaces", "xmlns:df='" & objDoc.documentElement.namespaceURI & "'"
          Debug.Print objNode.parentNode.nodeName & " heigth: " & objNode.parentNode.selectSingleNode("df:metatags/df:metatag[@name = 'heigth']").text
          Debug.Print objNode.parentNode.nodeName & " width: " & objNode.parentNode.selectSingleNode("df:metatags/df:metatag[@name = 'width']").text
          Problem dabei: Er arbeitet zwar genauso wie ich (wie ich es bisher will), aber er gibt jeden Wert der einmal drin steht, zwei mal aus (wenn ich debugge).

          Schaut ungefähr so aus dann im Direktfenster:
          image heigth: 2557
          image width: 2042
          image heigth: 2557
          image width: 2042
          image heigth: 2559
          image width: 1275
          image heigth: 2559
          image width: 1275
          image heigth: 2591
          image width: 1837

          WARUM?

          Comment


          • #6
            Dein Case testet ja "Select Case objNode.parentNode.nodeName" und dann Case "image", das passiert also für alle Kindsknoten eines "image"-Elementes. Davon gibt es in deinem Beispiel drei ("type", "filename", "metatags"), also sollte es drei Ausgaben geben, nicht zwei.

            So wirklich durchblicke ich deine Funktion nicht, wie gesagt, statt mich durch die childNodes zu hangeln und dabei nach gewissen Elementen zu suchen (oder noch komplizierter, nach gewissen parentNodes), würde ich einfach per XPath und selectNodes und selectSingleNode die Elemente heraussuchen, deren Daten ausgelesen werden sollen.

            Comment


            • #7
              Ich scheine mich etwas missverständlich ausgedrückt zu haben.
              Type und Filename lese ich NICHT aus (brauche ich nicht). Ich lese nur jeweils metatag-heigth und metatag-width aus.

              Beispiel: Wenn im ersten image Tag bei metatag-heigth 5 steht
              und beim ersten image Tag bei metatag-width 10 steht,
              dann gibt der debugger vier Werte aus (anstatt 2)
              So in etwa:
              heigth: 5
              width: 10
              heigth: 5
              width: 10

              Jeder Wert scheint doppelt eingelesen zu werden.

              Warum ich an der Case Struktur so "festhalte": Ich dachte damit kann ich den Programmablauf zur Berechnung von Werten steuern. Denn metatag-width und -heigth sollen nirgends ausgegeben werden, sondern zur Berechnung eines Wertes dienen.

              Diese vier Werte (und noch n paar andere) müssen in relation zueinader gebracht werden (mit ner Formel, die ich noch entwckeln muss).
              Preis_1c
              Hoehe
              Breite
              heigth
              width

              Da dacht ich mir, dass keine Elementen Anzahl oder sowas berechnet werden muss, wenn ich nach dem Case vorgehe. Denn pro <Meldung> soll quasi ein ergebnis ausgegeben werden. Dabei kann metatag-heigth und -width x-Mal vorkommen, der Rest im jeweiligen <Meldung> Block kommt nur einmal vor.
              Das wird aber so wie ich mir das vorgestellt habe glaube ich nicht ganz klappen, weil ich ja nirgends prüfe, wieviele images in einer Meldung sind.

              Jetzt muss ich erst mal das Problem mit den doppelten Datensätzen klären und dann die Formel überarbeiten.

              Für kluge Ratschläge immer offen.

              Und Danke nochmal für die bisherige Hilfe.

              Gruß
              J.R.

              Comment


              • #8
                Problem gelöst!

                siehe: http://www.office-loesung.de/ftopic435117_0_0_asc.php

                Danke auch an die Helfer hier aber!

                Comment

                Working...
                X