Anzeige
Archiv - Navigation
1824to1828
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Childnodes auslesen

Childnodes auslesen
07.04.2021 15:13:10
Sascha
Hallo.
meine VBA Kenntnisse sind noch nicht sehr ausgereift. Derzeit versuche ich neben der Arbeit durch viel lesen und ausprobieren diese zu erweitern. Momentan beschränke ich mich sehr auf das Thema XML und Auslesen mit Excel VBA, weil mir nichts anderes zur Verfügung steht. Der Rest klappt eh schon halbwegs :-)
Folgendes Problem. Ich versuche mittels XPath und SelectSingleNode bestimmte Daten aus dem beigefügtem XML abzugreifen und in ein Excel einzulesen. Das klappt soweit auch ganz gut.
Bei einem Punkt komme ich allerdings nicht weiter.
Das XML gliedert sich grob in accountreports je Kunde auf. Ich lese die Daten je accountreport aus und übertrage sie in eine Zeile nebeneinander.
Beim Knoten "Payment", bei dem ich gerne alle vorkommenden "Type"s und "PaymentAmnt"s je Kunde auslesen möchte, komme ich mit SelectSingleNodes natürlich nicht weiter, da der immer nur den ersten Datensatz auswirft.
"Type"s und "PaymentAmnt"s können je accountreport bis zu 4 mal vorkommen.
Ich habe nur keine Ahnung, wie ich die je accountreport abrufen kann und neben die weiteren Kundendaten setzen kann.
Mein Code bislang lautet (mit Sicherheit verbesserungswürdig)

Public Sub XML()
Dim objXML
Dim objNodeList
Dim objNodeList2
Dim objNode As MSXML2.IXMLDOMNode
Dim Zeile As Long
Sheets("Tabelle1").Cells.Clear
Zeile = 5
Set objXML = New MSXML2.DOMDocument60
objXML.validateOnParse = True
objXML.SetProperty "SelectionLanguage", "XPath"
' Dokument laden
If Not objXML.Load("R:\Test XML auslesen\Test XML\Test_1.XML") Then
' Fehler beim Laden
MsgBox "Fehler beim Laden des Dokumentes." & vbCrLf & vbCrLf _
& "Grund: " & objXML.parseError.reason & vbCrLf _
& "Zeile: " & objXML.parseError.Line, vbOKOnly Or vbExclamation, "Fehler"
Set objXML = Nothing
End If
objXML.SetProperty "SelectionLanguage", "XPath"
objXML.SetProperty "SelectionNamespaces", "xmlns:ftc=""urn:oecd:ties:fatca:v2"" xmlns:sfa="" _
_
_
_
urn:oecd:ties:stffatcatypes:v2"""
Set objNodeList = objXML.SelectNodes("/ftc:FATCA_OECD/ftc:FATCA/ftc:ReportingGroup/ftc: _
AccountReport")
For Each objNode In objNodeList
Debug.Print objNode.Text
With Worksheets("Tabelle1")
.Range("A" & Zeile).Value = objNode.SelectSingleNode("ftc:AccountNumber").Text
If Not objNode.SelectSingleNode("ftc:AccountHolder/ftc:Individual/sfa:TIN") Is  _
Nothing Then
.Range("B" & Zeile).Value = objNode.SelectSingleNode("ftc:AccountHolder/ftc: _
Individual/sfa:TIN").Text
End If
.Range("C" & Zeile).Value = objNode.SelectSingleNode("ftc:AccountHolder/ftc: _
Individual/sfa:Name/sfa:FirstName").Text
.Range("D" & Zeile).Value = objNode.SelectSingleNode("ftc:AccountHolder/ftc: _
Individual/sfa:Name/sfa:LastName").Text
.Range("E" & Zeile).Value = objNode.SelectSingleNode("ftc:AccountHolder/ftc: _
Individual/sfa:Address/sfa:AddressFix/sfa:Street").Text
.Range("F" & Zeile).Value = objNode.SelectSingleNode("ftc:AccountHolder/ftc: _
Individual/sfa:Address/sfa:AddressFix/sfa:PostCode").Text
.Range("G" & Zeile).Value = objNode.SelectSingleNode("ftc:AccountHolder/ftc: _
Individual/sfa:Address/sfa:AddressFix/sfa:City").Text
.Range("H" & Zeile).Value = objNode.SelectSingleNode("ftc:AccountBalance").Text
.Range("I" & Zeile).Value = objNode.SelectSingleNode("ftc:AccountBalance"). _
Attributes(0).Text
Zeile = Zeile + 1
End With
Next
Vielen Dank im voraus ;-)
End Sub

https://www.herber.de/bbs/user/145371.zip

7
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Childnodes auslesen
07.04.2021 16:21:30
ralf_b
du kannst die Nodes auch abfragen ob sie Childnodes haben und entsprechend dann durch diese per Schleife parsen
Alternativ ist mir aufgefallen das im objNode.text bereits die meisten Informationen vorliegen.
hier mal ein Beispiel für die Auswertung der Texteigenschaft mittels einem Array x2
da die Paymentinfos unbekannte Anzahl haben , anschließend eine Schleife über den Rest des Arrays

Dim x2
Dim i As Long
For Each objNode In objNodeList
Debug.Print objNode.Text
With Worksheets("Tabelle1")
x2 = Split(objNode.Text, " ")
.Range("A" & Zeile).Resize(, 8).Value = Array(x2(3), x2(5), x2(6), x2(7), x2(9) & " "  _
& x2(10), x2(11), x2(12), x2(14))
.Range("I" & Zeile).Value = objNode.SelectSingleNode("ftc:AccountBalance").Attributes( _
0).Text
For i = 1 To UBound(x2) - 14
.Cells(Zeile, 9).Offset(, i).Value = x2(14 + i)
Next
Zeile = Zeile + 1
End With
Next
Gruß
rb
Anzeige
AW: Childnodes auslesen
07.04.2021 16:58:21
Sascha
Vielen Dank. Bei dem Test XML funktioniert das tadellos. Mit dem Produktiv-XML habe ich noch leichte Unschärfen.
Hatte diese Abfrage eingebaut, weil manchmal diese Zeile /sfa:TIN nicht existiert
If Not objNode.SelectSingleNode("ftc:AccountHolder/ftc:Individual/sfa:TIN") Is Nothing Then
.Range("B" & Zeile).Value = objNode.SelectSingleNode("ftc:AccountHolder/ftc:Individual/sfa:TIN").Text
End If
Aber das Beispiel bringt mich schon weiter.
lG
Sascha
AW: Childnodes auslesen
09.04.2021 10:59:45
Sascha
Habe das jetzt irgendwie so gelöst. Performant ist anders, aber es erfüllt seinen Zweck
If objNode.SelectSingleNode("/ftc:FATCA_OECD/ftc:FATCA/ftc:ReportingGroup/ftc:AccountReport/ftc:Payment").HasChildNodes Then
For Each objNode2 In objNode.ChildNodes
For Each objNode3 In objNode2.ChildNodes
If objNode2.nodeName Like "ftc:Payment" Then
If objNode3.Text = "FATCA501" Then
Spalte = 10
End If
If objNode3.Text = "FATCA502" Then
Spalte = 13
End If
If objNode3.Text = "FATCA503" Then
Spalte = 16
End If
If objNode3.Text = "FATCA504" Then
Spalte = 19
End If
Cells(Zeile, 0 + Spalte) = objNode3.Text
If Not objNode3.Text Like "FATCA50*" Then
Cells(Zeile, 1 + Spalte) = objNode3.Attributes(0).Text
End If
Spalte = Spalte + 1
End If
Next
Next
End If
lG
Sascha
Anzeige
AW: Childnodes auslesen
09.04.2021 13:10:31
ralf_b
Mahlzeit,
verbirgt sich hinter diesem Post eine versteckte Frage nach mehr Performance?
ich vermute das du alle Nodes, auch die nicht im PaymentNode befindlichen nach den Paymentinhalten abfragst.
Einen Versuch meinerseits geb ich dir noch zum Spielen.
Public Sub XML()
Dim objXML
Dim objNodeList
Dim objNodeList2
Dim objNode As MSXML2.IXMLDOMNode, objNode2 As MSXML2.IXMLDOMNode, objNode3 As MSXML2. _
IXMLDOMNode
Dim Zeile As Long, Spalte As Long, lOffset As Long
Application.ScreenUpdating = False  'Bildschirmaktualisierung ausschalten
Sheets("Tabelle1").Cells.Clear
Zeile = 5
Set objXML = New MSXML2.DOMDocument60
objXML.validateOnParse = True
objXML.SetProperty "SelectionLanguage", "XPath"
' Dokument laden
If Not objXML.Load("F:\Downloads\Test_1.xml") Then
' Fehler beim Laden
MsgBox "Fehler beim Laden des Dokumentes." & vbCrLf & vbCrLf _
& "Grund: " & objXML.parseError.reason & vbCrLf _
& "Zeile: " & objXML.parseError.Line, vbOKOnly Or vbExclamation, "Fehler"
Set objXML = Nothing
End If
objXML.SetProperty "SelectionLanguage", "XPath"
objXML.SetProperty "SelectionNamespaces", "xmlns:ftc=""urn:oecd:ties:fatca:v2"" xmlns:sfa="" _
urn:oecd:ties:stffatcatypes:v2"""
Set objNodeList = objXML.SelectNodes("/ftc:FATCA_OECD/ftc:FATCA/ftc:ReportingGroup/ftc: _
AccountReport")
With Worksheets("Tabelle1")
For Each objNode In objNodeList
Debug.Print objNode.BaseName
If objNode.BaseName = "AccountReport" Then
If objNode.HasChildNodes Then
Debug.Print objNode.ChildNodes.Length
lOffset = 0
Spalte = 10
For Each objNode2 In objNode.ChildNodes
Select Case objNode2.BaseName
Case "AccountNumber"
Debug.Print "AccountNumber"
.Range("A" & Zeile).Value = objNode.SelectSingleNode("ftc: _
AccountNumber").Text
If Not objNode.SelectSingleNode("ftc:AccountHolder/ftc: _
Individual/sfa:TIN") Is Nothing Then
.Range("B" & Zeile).Value = objNode.SelectSingleNode("ftc: _
AccountHolder/ftc:Individual/sfa:TIN").Text
End If
Case "AccountHolder"
Debug.Print "AccountHolder"
Dim strXML As String
strXML = "ftc:Individual/"
.Range("C" & Zeile).Value = objNode2.SelectSingleNode(strXML & " _
sfa:Name/sfa:FirstName").Text
.Range("D" & Zeile).Value = objNode2.SelectSingleNode(strXML & " _
sfa:Name/sfa:LastName").Text
.Range("E" & Zeile).Value = objNode2.SelectSingleNode(strXML & " _
sfa:Address/sfa:AddressFix/sfa:Street").Text
.Range("F" & Zeile).Value = objNode2.SelectSingleNode(strXML & " _
sfa:Address/sfa:AddressFix/sfa:PostCode").Text
.Range("G" & Zeile).Value = objNode2.SelectSingleNode(strXML & " _
sfa:Address/sfa:AddressFix/sfa:City").Text
Case "AccountBalance"
Debug.Print "AccountBalance"
.Range("H" & Zeile).Value = objNode2.Text
.Range("I" & Zeile).Value = objNode2.Attributes(0).Text
Case "Payment"
Debug.Print "Payment"
.Cells(Zeile, Spalte + lOffset).Resize(, 2).Value = Split( _
objNode2.Text, " ")
lOffset = lOffset + 2 'spaltenversatz
Case Else
Debug.Print "im Else"
End Select
Next
Zeile = Zeile + 1
End If
End If
Next
End With
Application.ScreenUpdating = True
End Sub

Anzeige
Childnodes auslesen
10.04.2021 13:41:55
Anton
Hallo Sascha,
probier es hiermit:

Option Explicit
Sub b()
  Dim XML As Object, oReport As Object, oNode As Object  
  Dim lZeile As Long, iSpalte As Integer    
  Set XML = CreateObject("MSXML2.DOMDocument")  
  With XML
    .Load "C:\temp\145371\Test_1.xml" 'Pfad anpassen
    If .parseError.ErrorCode <> 0 Then  
      MsgBox "in Zeile:" & .parseError.Line & " " & _
        .parseError.srcText & vbCr & .parseError.reason, vbCritical, "Fehler"
    Else
      Application.ScreenUpdating = False
      Worksheets("Tabelle1").Cells.Clear
      lZeile = 5
      For Each oReport In .getelementsbytagname("ftc:AccountReport")  
        iSpalte = 1
        With Worksheets("Tabelle1")
          .Cells(lZeile, iSpalte) = oReport.getelementsbytagname("ftc:AccountNumber")(0).Text
          iSpalte = iSpalte + 1
          Set oNode = oReport.getelementsbytagname("sfa:TIN")(0)
          If Not oNode Is Nothing Then    
            .Cells(lZeile, iSpalte) = oNode.Text
            iSpalte = iSpalte + 1
          Else
            iSpalte = iSpalte + 1
          End If  
          .Cells(lZeile, iSpalte) = oReport.getelementsbytagname("sfa:FirstName")(0).Text
          iSpalte = iSpalte + 1
          .Cells(lZeile, iSpalte) = oReport.getelementsbytagname("sfa:LastName")(0).Text
          iSpalte = iSpalte + 1
          .Cells(lZeile, iSpalte) = oReport.getelementsbytagname("sfa:Street")(0).Text
          iSpalte = iSpalte + 1
          .Cells(lZeile, iSpalte) = oReport.getelementsbytagname("sfa:PostCode")(0).Text
          iSpalte = iSpalte + 1
          .Cells(lZeile, iSpalte) = oReport.getelementsbytagname("sfa:City")(0).Text
          iSpalte = iSpalte + 1
          Set oNode = oReport.getelementsbytagname("ftc:AccountBalance")(0)
          .Cells(lZeile, iSpalte) = oNode.Text & " " & oNode.Attributes(0).Text
          For Each oNode In oReport.getelementsbytagname("ftc:Payment")  
            If Not oNode Is Nothing Then    
              .Cells(lZeile, iSpalte) = oNode.Text
              iSpalte = iSpalte + 1
            End If  
          Next
          lZeile = lZeile + 1
        End With  
      Next
      Application.ScreenUpdating = True
    End If  
  End With  
  Worksheets("Tabelle1").Columns.AutoFit
  Set XML = Nothing  
End Sub

mfg Anton
Anzeige
AW: Childnodes auslesen
10.04.2021 14:09:00
Sascha
Vielen Dank. Das werde ich am Montag sofort ausprobieren.
Ein schönes Wochenende und liebe Grüße
kleine Korrektur
10.04.2021 15:06:38
Anton
Hallo nochmal,
          Set oNode = oReport.getelementsbytagname("ftc:AccountBalance")(0)
.Cells(lZeile, iSpalte) = oNode.Text & " " & oNode.Attributes(0).Text
iSpalte = iSpalte + 1 '!!!

mfg Anton

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige