Retrieve XML nodes not working with new file - excel

I have a code that succesfully retrieves the node values from XML files but I now have a file where it doesn`t work anymore, eventhough it is the same build up. Is it possible that it has something to do with the "_" sign in the XML? I already checked if I made a typo.
Snapshot of the XML where is works:
<?xml version="1.0" encoding="utf-8"?>
<!-- Automatically generated XML file -->
<ADEL:Report xmlns:ADEL="http://XMLSchema/MT/Generic/ADEL/v2.1.11">
<Header>
<Title>Lot Report</Title>
<MachineID>7</MachineID>
<MachineCustomerName>AT</MachineCustomerName>
<MachineType>X</MachineType>
<SoftwareRelease>at5.0.0.c</SoftwareRelease>
<CreatedBy></CreatedBy>
<CreateTime>2020-03-03T11:32:27.726447+01:00</CreateTime>
<MachineHostDeltaTime>0</MachineHostDeltaTime>
<Comment>
<elt></elt>
</Comment>
<DocumentId>20303-47</DocumentId>
<DocumentType>ADEL</DocumentType>
<DocumentTypeVersion>v2.1.11</DocumentTypeVersion>
<CategoryList></CategoryList>
</Header>
</ADEL:Report>
Snapshot of the XML file where it doesn`t work:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Automatically generated XML file -->
<ADEL:Definitions xmlns:ADEL="http://XMLSchema/MT/TWIN/ADEL/v6.2.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://XMLSchema/MT/TWIN/ADEL/v6.2.1 ADEL.xsd">
<RecipeCollection>
<UnitRecipe>
<RecipeStep>
<RECIPE>
<RECIPE_DATA>
<RECIPE_GENERAL_DATA>
<RECIPE_NAME>
<PPID>user_data/RDM/BACKUP</PPID>
</RECIPE_NAME>
<GENERAL_DATA>
<CREATED_BY></CREATED_BY>
<CREATED_TIME>2020-05-16T16:13:49.879847+02:00</CREATED_TIME>
<LAST_MODIFIED_BY></LAST_MODIFIED_BY>
<LAST_MODIFIED_TIME>2020-08-12T09:16:07.409547+02:00</LAST_MODIFIED_TIME>
<STORAGE_MODIFICATION_NR>8</STORAGE_MODIFICATION_NR>
<COMMENT_ARRAY>
<elt><This Formatted Process Program was created from an exported recipe.>
</elt>
</COMMENT_ARRAY>
</GENERAL_DATA>
<SOFTREV>6.2.0.b</SOFTREV>
<LAST_EXPORTED_BY></LAST_EXPORTED_BY>
<LAST_EXPORTED_TIME>2020-08-12T09:16:07.409547+02:00</LAST_EXPORTED_TIME>
<EXPORTED_FROM_STORAGE>8</EXPORTED_FROM_STORAGE>
<EXPORT_MODIFICATION_NR>8</EXPORT_MODIFICATION_NR>
<CALIBRATION_STATE_ID>DEFAULT</CALIBRATION_STATE_ID>
</RECIPE_GENERAL_DATA>
</RECIPE_DATA>
</RECIPE>
</RecipeStep>
</UnitRecipe>
</RecipeCollection>
</ADEL:Definitions>
Code used:
Dim wb As Workbook
Dim FilePath As String
Set wb = ThisWorkbook
FilePath = Application.ActiveWorkbook.Path
MaskId = wb.Sheets("Sheet1").Range("E1").Value
Set oXMLFile = CreateObject("Microsoft.XMLDOM")
XMLFileName = Dir(FilePath & "\" & MaskId & "*.xml")
If XMLFileName = "" Then
MsgBox "no file found"
Else
End If
Debug.Print XMLFileName = ""
oXMLFile.Load (XMLFileName)
MsgBox oXMLFile.validateOnParse
Set MaskNodes = oXMLFile.SelectNodes("/ADEL:Definitions/RecipeCollection/UnitRecipe/RecipeStep/RECIPE/RECIPE_DATA/RECIPE_GENERAL_DATA/SOFTREV/text()")
'Below is working for the other XML file
'Set MaskNodes = oXMLFile.SelectNodes("/ADEL:Report/Input/LotSettings/LotType/text()")
MsgBox MaskNodes(i).NodeValue

Related

Having trouble with XML phase on VBA Excel

I need to parse a XML file having the structure as follows: (I can't show the data as it is confidential)
<?xml version="1.0" encoding="UTF-8"?>
<GACDWBulkLoadInterface xsi:schemaLocation="http://www.example.org/GACDWSchema GACDWSchema.xsd" xmlns="http://www.example.org/GACDWSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<BLConfiguration>
<BLProperties>
<BLProperty>
<key>isEmpty</key>
<value xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="xsd:boolean">true</value>
</BLProperty>
</BLProperties>
<version>api-ag-1.1.68-20210315-43</version>
</BLConfiguration>
<Customer>
<CustomerID></CustomerID>
<Customer_Name></Customer_Name>
<ISOCountryCode></ISOCountryCode>
<customerType></customerType>
<dataSourceProvider></dataSourceProvider>
<function></function>
<TopLevelCI>
<Contact Action="Create">
<Id>4</Id>
<artifactType></artifactType>
<contactType></contactType>
<email></email>
<firstName></firstName>
<lastName></lastName>
<userID></userID>
<ChildCI/>
</Contact>
<PhysicalComputerSystem Action="Create">
<Id>2</Id>
<artifactType></artifactType>
<assetLifeCycleState></assetLifeCycleState>
<category></category>
<ciLifeCycleState></ciLifeCycleState>
<custname></custname>
<description></description>
<discontinuedDate></discontinuedDate>
<machineType></machineType>
<managed></managed>
<manufacturer></manufacturer>
<model></model>
<serialNumber></serialNumber>
<virtualFlag></virtualFlag>
<ChildCI>
<PhysicalComputerSystemContact Action="Create">
<contactUID></contactUID>
</PhysicalComputerSystemContact>
<PhysicalComputerSystemLocation Action="Create">
<buildingID></buildingID>
<buildingName></buildingName>
<city></city>
<countryName></countryName>
<isoCountryCode></isoCountryCode>
<postalCode></postalCode>
<siteName></siteName>
<stateProvince></stateProvince>
<streetAddress></streetAddress>
</PhysicalComputerSystemLocation>
</ChildCI>
</PhysicalComputerSystem>
<OperatingSystem Action="Create">
<Id>1</Id>
<aliasHostname></aliasHostname>
<artifactType></artifactType>
<assetLifeCycleState></assetLifeCycleState>
<backupContr></backupContr>
<barSaId></barSaId>
<cacfCustomGroup></cacfCustomGroup>
<category></category>
<ciLifeCycleState></ciLifeCycleState>
<classification></classification>
<cpuCount></cpuCount>
<description></description>
<discontinuedDate></discontinuedDate>
<fqhn></fqhn>
<hostsystemID></hostsystemID>
<hostsystemType></hostsystemType>
<installationDate></installationDate>
<ipAddress></ipAddress>
<majorBusProc></majorBusProc>
<managed></managed>
<memory></memory>
<memoryUnit></memoryUnit>
<osModLevel></osModLevel>
<osName></osName>
<osBuildNumber></osBuildNumber>
<osProvider></osProvider>
<osRelease></osRelease>
<osVersion></osVersion>
<prodDate></prodDate>
<purgeDate></purgeDate>
<purpose></purpose>
<securityClass></securityClass>
<serverType></serverType>
<supportEnddate></supportEnddate>
<useAliasHostname></useAliasHostname>
<virtualFlag></virtualFlag>
<ChildCI>
<OperatingSystemContact Action="Create">
<contactUID></contactUID>
</OperatingSystemContact>
<OperatingSystemEnvironmentProfile Action="Create">
<authFlag></authFlag>
<authExceptDate></authExceptDate>
<authExceptReasonCode></authExceptReasonCode>
<authExceptText></authExceptText>
<disasterRecSys></disasterRecSys>
<domain></domain>
<extUsersMax></extUsersMax>
<hcAutoInterv></hcAutoInterv>
<hcExceptDate></hcExceptDate>
<hcExceptReasonCode></hcExceptReasonCode>
<hcExceptText></hcExceptText>
<hcUnit></hcUnit>
<healthchAutoFlag></healthchAutoFlag>
<highestClientDataClassification></highestClientDataClassification>
<highestDataClassification></highestDataClassification>
<highestIbmDataClassification></highestIbmDataClassification>
<ibmCbnInterval></ibmCbnInterval>
<ibmCbnRequired></ibmCbnRequired>
<ibmCbnType></ibmCbnType>
<ibmCbnUnit></ibmCbnUnit>
<ibmPrivIDUnit></ibmPrivIDUnit>
<ibmPrivType></ibmPrivType>
<ibmQevFlag></ibmQevFlag>
<ibmQevInterval></ibmQevInterval>
<ibmQevUnit></ibmQevUnit>
<ibmUsersMax></ibmUsersMax>
<internetAccFlag></internetAccFlag>
<personalData></personalData>
<privIDFlag></privIDFlag>
<privIDInterv></privIDInterv>
<regulatoryRequirements></regulatoryRequirements>
<remediationtimeHi></remediationtimeHi>
<remediationtimeLo></remediationtimeLo>
<remediationtimeMd></remediationtimeMd>
<rerFlag></rerFlag>
<rerInterv></rerInterv>
<rerType></rerType>
<rerUnit></rerUnit>
<scExceptDate></scExceptDate>
<scExceptReasonCode></scExceptReasonCode>
<scExceptText></scExceptText>
<secExemptionDesc></secExemptionDesc>
<secExemptionFlag></secExemptionFlag>
<securityPackage></securityPackage>
<securityPolicyCategory></securityPolicyCategory>
<securityPolicyOther></securityPolicyOther>
<securityPolicyType></securityPolicyType>
<serverPurpose></serverPurpose>
<sharedIDFlag></sharedIDFlag>
<shrdExceptDate></shrdExceptDate>
<shrdExceptReasonCode></shrdExceptReasonCode>
<shrdExceptText></shrdExceptText>
<vitalBusProcessYN></vitalBusProcessYN>
</OperatingSystemEnvironmentProfile>
<OperatingSystemIpAddress Action="Create">
<dotnotation></dotnotation>
<hostName></hostName>
<isPrimaryIpHost></isPrimaryIpHost>
<name></name>
<netMask></netMask>
<vsExceptDate></vsExceptDate>
<vsExceptReasonCode></vsExceptReasonCode>
<vsExceptText></vsExceptText>
<vulScanUnit></vulScanUnit>
<vulscanAutoFlag></vulscanAutoFlag>
<vulscanAutoInterval></vulscanAutoInterval>
</OperatingSystemIpAddress>
</ChildCI>
</OperatingSystem>
<Subsystem Action="Create">
<Id>3</Id>
<applSIDataType></applSIDataType>
<artifactType></artifactType>
<assetLifeCycleState></assetLifeCycleState>
<ciLifeCycleState></ciLifeCycleState>
<controlProductName></controlProductName>
<controlProductRelease></controlProductRelease>
<controlProductType></controlProductType>
<controlProductVendor></controlProductVendor>
<controlProductVersion></controlProductVersion>
<description></description>
<discontinuedDate></discontinuedDate>
<fqhn></fqhn>
<managed></managed>
<name></name>
<parentUID></parentUID>
<piFlag></piFlag>
<productModLevel></productModLevel>
<productName></productName>
<productPatchLevel></productPatchLevel>
<productRelease></productRelease>
<productVersion></productVersion>
<purgeDate></purgeDate>
<scanTime></scanTime>
<vendorName></vendorName>
<ChildCI>
<SubsystemContact Action="Create">
<contactUID></contactUID>
</SubsystemContact>
<SubsystemEnvironmentProfile Action="Create">
<authFlag></authFlag>
<authExceptDate></authExceptDate>
<authExceptReasonCode></authExceptReasonCode>
<authExceptText></authExceptText>
<disasterRecSys></disasterRecSys>
<hcAutoInterv></hcAutoInterv>
<hcExceptDate></hcExceptDate>
<hcExceptReasonCode></hcExceptReasonCode>
<hcExceptText></hcExceptText>
<hcUnit></hcUnit>
<healthchAutoFlag></healthchAutoFlag>
<ibmCbnInterval></ibmCbnInterval>
<ibmCbnRequired></ibmCbnRequired>
<ibmCbnType></ibmCbnType>
<ibmCbnUnit></ibmCbnUnit>
<ibmPrivIDUnit></ibmPrivIDUnit>
<ibmPrivType></ibmPrivType>
<ibmQevFlag></ibmQevFlag>
<ibmQevInterval></ibmQevInterval>
<ibmQevUnit></ibmQevUnit>
<privIDFlag></privIDFlag>
<privIDInterv></privIDInterv>
<rerFlag></rerFlag>
<rerInterv></rerInterv>
<rerType></rerType>
<rerUnit></rerUnit>
<scExceptDate></scExceptDate>
<scExceptReasonCode></scExceptReasonCode>
<scExceptText></scExceptText>
<sharedIDFlag></sharedIDFlag>
<shrdExceptDate></shrdExceptDate>
<shrdExceptReasonCode></shrdExceptReasonCode>
<shrdExceptText></shrdExceptText>
<vitalBusProcessYN></vitalBusProcessYN>
</SubsystemEnvironmentProfile>
</ChildCI>
</Subsystem>
</TopLevelCI>
<Relationship>
<RelationshipName>Hosted_by</RelationshipName>
<sourceCIType>OperatingSystem</sourceCIType>
<targetCIType>OperatingSystem</targetCIType>
</Relationship>
<Relationship>
<RelationshipName>Runs_on</RelationshipName>
<sourceCIType>Subsystem</sourceCIType>
<targetCIType>OperatingSystem</targetCIType>
</Relationship>
<Relationship>
<RelationshipName>Runs_on_hw</RelationshipName>
<sourceCIType>OperatingSystem</sourceCIType>
<targetCIType>PhysicalComputerSystem</targetCIType>
</Relationship>
</Customer>
</GACDWBulkLoadInterface>
I have researched and come up with my VBA code here
Sub ReadXML()
Dim oXML As MSXML2.DOMDocument60
Dim vaFile As Variant
Set oXML = New MSXML2.DOMDocument60
'Open Browse file dialog
vaFile = Application.GetOpenFilename("XML Files (*.xml), *.xml", _
Title:="Select XML files", MultiSelect:=False)
oXML.validateOnParse = True
oXML.setProperty "SelectionLanguage", "XPath" ' necessary in version 3.0, possibly redundant here
oXML.async = False
If Not oXML.Load(vaFile) Then 'Load XML has gone bad
Dim xPE As Object ' Set xPE = CreateObject("MSXML2.IXMLDOMParseError")
Dim strErrText As String
Set xPE = oXML.parseError
With xPE
strErrText = "Load error " & .ErrorCode & " xml file " & vbCrLf & _
Replace(.URL, "file:///", "") & vbCrLf & vbCrLf & _
xPE.reason & _
"Source Text: " & .srcText & vbCrLf & vbCrLf & _
"Line No.: " & .Line & vbCrLf & _
"Line Pos.: " & .linepos & vbCrLf & _
"File Pos.: " & .filepos & vbCrLf & vbCrLf
End With
MsgBox strErrText, vbExclamation
Set xPE = Nothing
Exit Sub
End If
Debug.Print "|" & oXML.XML & "|"
Dim nodeList As MSXML2.IXMLDOMNodeList, iNode As MSXML2.IXMLDOMNode
Dim Searched As String
Searched = "/*/*"
Set nodeList = oXML.SelectNodes(Searched)
'Set Queries = oXML.DocumentElement.SelectNodes(Searched)
For Each iNode In nodeList
'Debug.Print "<" & iNode.BaseName & ">"
Debug.Print "<" & iNode.nodeName & ">"
Next
However, My problem is no matter what I come up with Xpath queries. None of them work except \* or \.
I can't specific any path. Both .SelectSingleNode or .SelectNodes alway return length =0. Is there any problem with my code or my XML file or Xpath syntax?
As mentioned in comments your xml document has namespace definitions in its DocumentElement <GACDWBulkLoadInterface> (xmlns stands for xml name space). Furthermore "it contains a default namespace so any attempted parsing on named nodes must map to this namespace URI otherwise returns nothing."
To allow eventual analysis it's necessary to include a user defined prefix (e.g. :s) into explicit namespace settings, which can be used in later XPath expressions:
Dim oXML As MSXML2.DOMDocument60
Set oXML = New MSXML2.DOMDocument60
oXML.validateOnParse = True
Dim XMLNamespaces As String
XMLNamespaces = "xmlns:s='http://www.example.org/GACDWSchema'"
oXML.SetProperty "SelectionNamespaces", XMLNamespaces
Eventually you can define any XPath expression, e.g. the childnodes of Customer[1]:
Dim nodeList As MSXML2.IXMLDOMNodeList, iNode As MSXML2.IXMLDOMNode
Dim Searched As String
Searched = "//s:Customer/s:*"
Set nodeList = oXML.SelectNodes(Searched)
Related links
Displaying XML structures including attributes via recursive function calls
Display XML with hierarchy in cells
Apparently OP's source code: Parse DomDocument

How to Import multiple XML Files into Excel with VBA without overwriting the files that have already been imported

I have a directory with multiple XML-Files. New XML-Files are added to the directory every day.
I´m trying to import those XML-Files into one specific Excel Sheet everyday, without overwriting the existing data in my Excel Sheet.
I have already managed to import the XML-Files.
Question 1: How can I Import the XML-Files without headings or xml path?
Question 2: Is there a way to only import new data and skip the files I already have imported
Hope anyone can help me out with this. Trying to find a solution for quite a long time and couldn´t find an answer by myself or online.
This is the Structure of my XML-Files:
<?xml version="1.0" encoding="utf-8"?>
<MFK_XML xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Auftrag>
<WarenkorbReferenz>0</WarenkorbReferenz>
<JobNr>12345-999</JobNr>
<KuNr>12345</KuNr>
<ReNr>7</ReNr>
<SoA>0</SoA>
<Termin>2020-03-10</Termin>
<Versandtermin>2020-03-09</Versandtermin>
<Gewicht>1.1037620</Gewicht>
<Datencheck>0</Datencheck>
<Proof>0</Proof>
<Kundenhinweis />
<Auflage>5</Auflage>
<Versionen>1</Versionen>
<Gesamtpreis>15.50</Gesamtpreis>
<Priority>S</Priority>
<ProduktionsTage>5</ProduktionsTage>
<Mandant />
<LNr>151</LNr>
<IVB>10</IVB>
<Gratis>0</Gratis>
<Transfer>2020-03-02</Transfer>
</Auftrag>
<Artikel>
<Artikelbezeichnung>Broschüre mit Metall-Spiralbindung, Endformat DIN A4, 48-seitig</Artikelbezeichnung>
<ArtikelID>12345</ArtikelID>
<ArtStr>Flex</ArtStr>
<ProdKrzl>FlX</ProdKrzl>
<Sorte>135g Innenteil mit 250g Umschlag (matt, hochwertiger Qualitätsdruck, 4/4-farbig)</Sorte>
<SortenID>152</SortenID>
<Seitenzahl>48</Seitenzahl>
<SeitenZahlMalVersionen>48</SeitenZahlMalVersionen>
<Seitenzahlgesamt>48</Seitenzahlgesamt>
<SeitenzahlInhalt />
<SeitenzahlUmschlag />
<Farbigkeit>44</Farbigkeit>
<FarbigkeitInhalt />
<FarbigkeitUmschlag />
<PapierInnen>135g Innenteil</PapierInnen>
<PapierUmschlag>250g Umschlag (matt, hochwertiger Qualitätsdruck, 4/4-farbig)</PapierUmschlag>
<Endformat_mm_X>210</Endformat_mm_X>
<Endformat_mm_Y>297</Endformat_mm_Y>
<Datenformat_mm_X>216</Datenformat_mm_X>
<Datenformat_mm_y>303</Datenformat_mm_y>
<FormatUmschlag_x />
<FormatUmschlag_y />
<EndFormatUmschlag_x />
<EndFormatUmschlag_y />
<Falzart>0</Falzart>
<Falzlauf />
<gefendFormat_x />
<gefendFormat_y />
<BeschnittI>3</BeschnittI>
<BeschnittU />
<Bundstaerke>3</Bundstaerke>
<vWd>0</vWd>
<pWd>0</pWd>
<vUV>0</vUV>
<pUV>0</pUV>
<Rillung>0</Rillung>
<KissCut>0</KissCut>
<Druckverfahren>Druck</Druckverfahren>
<dataformat>pdf</dataformat>
<Zusatzinfo>Schwarz</Zusatzinfo>
</Artikel>
<Optionen>
<Veredelung>0</Veredelung>
<Falzung>0</Falzung>
<Ausrichtung>0</Ausrichtung>
<Heften>0</Heften>
<Nutung>0</Nutung>
<Buendelung>0</Buendelung>
<Leimung>0</Leimung>
<Perforierung>0</Perforierung>
<Sonderfarbe>0</Sonderfarbe>
<Lochbohrungen_Ecken>0</Lochbohrungen_Ecken>
<Nummerierung>0</Nummerierung>
<Barcode>0</Barcode>
<Hologramm>0</Hologramm>
<Abheftvorrichtung>0</Abheftvorrichtung>
<Cello>
<Cellophaniert>0</Cellophaniert>
<CelloArt>0</CelloArt>
</Cello>
<stanze>
<StanzeForm>keine</StanzeForm>
<StanzeOffset>0</StanzeOffset>
</stanze>
<Einschweissen>0</Einschweissen>
<Fadenheftung>0</Fadenheftung>
<Werbefolie>0</Werbefolie>
<Ecken_abrunden>0</Ecken_abrunden>
<RAL_Farbe>0</RAL_Farbe>
<Gummiband_Verschluss>0</Gummiband_Verschluss>
<HKS_Pantone>0</HKS_Pantone>
<Lochung>0</Lochung>
<PP_Deck>0</PP_Deck>
<DeckBl_V>0</DeckBl_V>
<DeckBl_V_H>0</DeckBl_V_H>
<Praegung>0</Praegung>
<Rubbelfeld>0</Rubbelfeld>
<Magnetstreifen>0</Magnetstreifen>
<Unterschriftsfeld>0</Unterschriftsfeld>
<Magnetpunkt_Verschluss>0</Magnetpunkt_Verschluss>
<Griffloch>0</Griffloch>
<Verchromte_Buchecken>0</Verchromte_Buchecken>
<Rueckentasche>0</Rueckentasche>
<Visitenkartentasche>0</Visitenkartentasche>
<Dreieckstasche>0</Dreieckstasche>
<Kombitasche>0</Kombitasche>
<CD_Tasche>0</CD_Tasche>
<Radooesen>0</Radooesen>
<Postkarten_indiv_personalisieren>0</Postkarten_indiv_personalisieren>
<LED_Halogenbeleuchtung>0</LED_Halogenbeleuchtung>
<Klima>1</Klima>
</Optionen>
<Zusatzkosten />
<Dateien>
<Dateiname>12345-999.pdf</Dateiname>
</Dateien>
<WF_Name>
<WF_Name>12345-999.pdf</WF_Name>
</WF_Name>
</MFK_XML>
Here´s the Code of the VBA:
Sub From_XML_To_XL()
Dim xWb As Workbook
Dim xSWb As Workbook
Dim xStrPath As String
Dim xFileDialog As FileDialog
Dim xFile As String
Dim xCount As Long
On Error GoTo ErrHandler
Set xFileDialog = Application.FileDialog(msoFileDialogFolderPicker)
xFileDialog.AllowMultiSelect = False
xFileDialog.Title = "Select a folder"
If xFileDialog.Show = -1 Then
xStrPath = xFileDialog.SelectedItems(1)
End If
If xStrPath = "" Then Exit Sub
Application.ScreenUpdating = False
Set xSWb = ThisWorkbook
xCount = 1
xFile = Dir(xStrPath & "\*.xml")
Do While xFile <> ""
Set xWb = Workbooks.OpenXML(xStrPath & "\" & xFile)
xWb.Sheets(1).UsedRange.Copy xSWb.Sheets(1).Cells(xCount, 1)
xWb.Close False
xCount = xSWb.Sheets(1).UsedRange.Rows.Count + 2
xFile = Dir()
Loop
Application.ScreenUpdating = True
xSWb.Save
Exit Sub
ErrHandler:
MsgBox "no files xml"
End Sub
Consider XSLT, the special-purpose language to transform XML files, which you can use its document() function to combine all XMLs in the directory. Then, import the resulting transformed file as one document into Excel. Office VBA can run XSLT 1.0 with the MSXML library.
Below assumes exact structure is retained in all XML files (regardless of recurring elements) where each document maps to root level <MFK_XML>. Add to the below <xsl:copy-of ...> lines for each document. Should you have hundreds, consider building XSLT document in a loop with VBA, Python, etc. If files are relatively small as posted, XSLT is a viable solution but does have memory limitations.
XSLT (save as .xsl, a special .xml file)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/MFK_XML">
<MFK_XML>
<xsl:copy-of select="document('First.xml')/MFK_XML/*" />
<xsl:copy-of select="document('Second.xml')/MFK_XML/*" />
<xsl:copy-of select="document('Third.xml')/MFK_XML/*" />
<!-- ADD: <xsl:copy-of select="document('XXXX.xml')/MFK_XML/*" /> -->
</MFK_XML>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
VBA (no loop is needed)
Sub XSLTransform()
On Error GoTo ErrHandle
' ENABLE Microsoft XML, v#.# IN REFERENCES
Dim xmldoc As New MSXML2.DOMDocument60, xslDoc As New MSXML2.DOMDocument60
Dim newDoc As New MSXML2.DOMDocument60
Dim xWb As Workbook
' LOAD XML AND XSL FILES
xmldoc.async = False
xmldoc.Load "C:\Path\To\Any.xml"
xslDoc.async = False
xslDoc.Load "C:\Path\To\Script.xsl"
xslDoc.setProperty "AllowDocumentFunction", True
' TRANSFORM XML
xmldoc.transformNodeToObject xslDoc, newDoc
newDoc.Save "C:\Path\To\Transformed.xml"
Set xWb = Workbooks.OpenXML("C:\Path\To\Transformed.xml")
xWb.SaveAs "C:\Path\To\Final.xlsx"
xWb.Close False
ExitHandle:
Set xmldoc = Nothing: Set xslDoc = Nothing: Set newDoc = Nothing
Set xWb = Nothing
Exit Sub
ErrHandle:
MsgBox Err.Number & " - " & Err.Description, vbCritical
Resume ExitHandle
End Sub

XML parse VBA excel (function trip, & MSXML2.DOMDocument)

I need to parse hundreds of XML files having all the same structure as follows:
<?xml version="1.0" encoding="UTF-8"?>
<Concepts>
<ConceptModel name="food">
<Filters>
<Filter type="CC"/>
</Filters>
<Queries>
<Query lang="EN">(cheese, bread, wine)</Query>
<Query lang="DE">(Käse, Brot, Wein)</Query>
<Query lang="FR">(fromaige, pain, vin)</Query>
</Queries>
</ConceptModel>
</Concepts>
I have read several articles and posts in internet like below but I could not come up with a solution:
Excel vba Parse Complex XML
Parse XML File with VBA
So far I am doing:
Dim oXml As MSXML2.DOMDocument
Set oXml = New MSXML2.DOMDocument
oXml.LoadXML ("C:\folder\folder\name.xml")
Dim Queries As IXMLDOMNodeList
Dim Query As IXMLDOMNode
ThisWorkbook.Sheets(3).Cells(i, 1) = "before loop"
Set Queries = oXml.SelectNodes("/concepts/Queries")
MsgBox "how many Queries " & Queries.Length
For Each Query In Queries
ThisWorkbook.Sheets(3).Cells(i, 1) = "Works"
ThisWorkbook.Sheets(3).Cells(i, 2) = Query.SelectNodes("Query").iTem(0).Text
i = i + 1
Next
This code seems to be understood by VBA but it does not read the contents. The loop does not get read, meaning (I guess) that Queries is not looped at all. Which is confirmed by the fact that the Msgbox "how many queries" gives 0 as result. But actually there are three queries. Could someone give me a hand?
As second issue I would like to ask if
Dim oXml As MSXML2.DOMDocument
would be the same as
Dim oXml As MSXML2.DOMDocument60
Since I checked in tools/references "Microsof XML, v6.0"
I thought that the queries having a tag
might cause a problem. and I added the follwoing lines:
Dim childs As IXMLDOMNodeList
Set childs = oXml.SelectNodes("/concepts")
MsgBox "childs " & childs.Length
which also gives 0 as result. I would expect 3, since concepts has three children, namely ConceptModel, Filter and Queries. So, I am even more puzzled.
As close as possible to your OP
I 'd draw your attention to several errors or misunderstandings:
[1] Invalid .LoadXML Syntax
What is then the difference between .LoadXML ("C:\folder\folder\name.xml") and .Load ("C:\folder\folder\name.xml") ?
Load expects a file path and then loads the file content into the oXML object.
LoadXML doesn't expect a file parameter, but its actual XML text content that has to be a well formed string.
[2] XML distinguishes between lower and upper case, therefore nodes need to be addressed by their exact literal names:
the <Query> node wouldn't be identified by "query", "ConceptModel" isn't the same as "conceptmodel".
As second issue I would like to ask if
Dim oXml As MSXML2.DOMDocument would be the same as
Dim oXml As MSXML2.DOMDocument60,
since I checked in tools/references "Microsof XML, v6.0"?
No, it isn't. - Please note that the former declaration would load version 3.0 by default.
However it's absolutely preferrable to get the version 6.0 (any other versions are obsolete nowadays!)
As you are using so called early binding (referencing "Microsoft XML, v6.0"), I'll do the same but am referring to the current version 6.0:
Dim oXml As MSXML2.DOMDocument60 ' declare the xml doc object
Set oXml = New MSXML2.DOMDocument60 ' set an instance of it to memory
[3] misunderstanding some XPath expressions
A starting slash "/" in the XPath expression always refers to the DocumentElement (<Concepts> here),
you can add .DocumentElement to your document object instead. A starting double slash "//xyz" would find any "xyz" node if existant.
For instance
oXml.SelectNodes("//Query").Length
returns the same childNodes number (here: 3) as
oXml.DocumentElement.SelectNodes("//Query").Length ' or
oXml.SelectSingleNode("//Queries").ChildNodes.Length ' or even
oXml.SelectNodes("/*/*/*/Query").Length`.
Code example with reference to XML version 6.0
Of course you'd have to loop over several xml files, the example only uses one (starting in row 2).
Just for the case of not well formed xml files I added a detailled error Routine that enables you to identify the presumed error location. Load and LoadXML both return a boolean value (True if loaded correctly, False if not).
Sub xmlTest()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets(3)
Dim oXml As MSXML2.DOMDocument60
Set oXml = New MSXML2.DOMDocument60
With oXml
.validateOnParse = True
.setProperty "SelectionLanguage", "XPath" ' necessary in version 3.0, possibly redundant here
.async = False
If Not .Load(ThisWorkbook.Path & "\xml\" & "name.xml") Then
Dim xPE As Object ' Set xPE = CreateObject("MSXML2.IXMLDOMParseError")
Dim strErrText As String
Set xPE = .parseError
With xPE
strErrText = "Load error " & .ErrorCode & " xml file " & vbCrLf & _
Replace(.URL, "file:///", "") & vbCrLf & vbCrLf & _
xPE.reason & _
"Source Text: " & .srcText & vbCrLf & vbCrLf & _
"Line No.: " & .Line & vbCrLf & _
"Line Pos.: " & .linepos & vbCrLf & _
"File Pos.: " & .filepos & vbCrLf & vbCrLf
End With
MsgBox strErrText, vbExclamation
Set xPE = Nothing
Exit Sub
End If
' Debug.Print "|" & oXml.XML & "|"
Dim Queries As IXMLDOMNodeList, Query As IXMLDOMNode
Dim Searched As String
Dim i&, ii&
i = 2 ' start row
' start XPath
Searched = "ConceptModel/Queries/Query" ' search string
Set Queries = oXml.DocumentElement.SelectNodes(Searched) ' XPath
'
ws.Cells(i, 1) = IIf(Queries.Length = 0, "No items", Queries.Length & " items")
ii = 1
For Each Query In Queries
ii = ii + 1
ws.Cells(i, ii) = Query.Text
Next
End With
End Sub
Additional hints
You also might be interested in an example how to list all child nodes via XMLDOM and to obtain attribute names from XML using VBA.
I include a further hint due to later comment (thanks to #barrowc )
"A further issue with using MSXML, v3.0 is that the default selection language is XSLPatterns instead of XPath.
Details on some of the differences between MSXML versions are here
and the differences between the two selection languages are discussed here."
In the current MSXML2 version 6.0 XPath 1.0 is fully supported. So it seems XSL Patterns have been implemented by Microsoft in earlier days, basically it can be regarded as a simplified subset of XPath expressions before W3C standardisation of XPath.
MSXML2 Version 3.0 allows the integration of XPath 1.0 at least by explicit selection language setting:
oXML.setProperty "SelectionLanguage", "XPath" ' oXML being the DOMDocument object as used in original post
It is the special characters (german alphabet) meaning you need to do something like a batch replace on the XML files so opening line is not this:
<?xml version="1.0" encoding="UTF-8"?>
but this:
<?xml version="1.0" encoding="iso-8859-1" ?>
Code to test with after:
Option Explicit
Public Sub test()
Dim xmlDoc As Object
Set xmlDoc = CreateObject("MSXML2.DOMDocument") 'New MSXML2.DOMDocument60
With xmlDoc
.validateOnParse = True
.setProperty "SelectionLanguage", "XPath"
.async = False
If Not .Load("C:\Users\User\Desktop\Test.xml") Then
Err.Raise .parseError.ErrorCode, , .parseError.reason
End If
End With
Debug.Print xmlDoc.SelectNodes("//Query").Length
End Sub
This is the XML I am using:
<?xml version="1.0" encoding="iso-8859-1" ?>
<Concepts>
<ConceptModel name="food">
<Filters>
<Filter type="CC"/>
</Filters>
<Queries>
<Query lang="EN">(cheese, bread, wine)</Query>
<Query lang="DE">(Käse, Brot, Wein)</Query>
<Query lang="FR">(fromaige, pain, vin)</Query>
</Queries>
</ConceptModel>
</Concepts>

Downloading an excel add in from Sharepoint using VBA

I have an excel file that when opened needs to download and open the latest version of an add in that is stored in Sharepoint. I have this code that downloads the add in, saves it in a specific location (strSavePath) and tries to open it.
Function funLoadRomeFiles(strURL As String, strSavePath As String)
Dim objConnection As Object
Dim objStream As Object
Set objConnection = CreateObject("MSXML2.ServerXMLHTTP.6.0")
On Error GoTo ExitConnect
objConnection.Open "GET", strURL, False
objConnection.send
strURL = objConnection.responseBody
If objConnection.Status = 200 Then
Set objStream = CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = 1
objStream.Write objConnection.responseBody
objStream.SaveToFile strSavePath, 2
objStream.Close
End If
ExitConnect:
On Error GoTo 0
Shell "C:\WINDOWS\explorer.exe """ & strSavePath & "", vbHide
End Function
However I get an error on the second to last row. The error is: Excel cannot open the file "Filename" because the file format or file extension is not valid [...]". The file downloaded is corrupted and cannot be opened manually either. When I download it and open it manually , it works.
The file size is 30.9 kb, but executing the code will download it as a 51 kb file. I've tried downloading other files using this code, and they have also become corrupted and 51 kb no matter the actual file size. Is there any way to change the code so the file will not be corrupted or any other ways of doing this?
Update: The file downloaded seems to be a html file even though its name still ends with .xlam
Also, I,ve tried using a link that ends with "filename.xlam" and one that ends with "filename.xlam?csf=1&e=b5f7991021ab45c1833229210f3ce810", both gives the same result, and when you copy the links into chrome both immediately downloads the correct file
I had a once a similar Problem.
The Problem by me was, that sharepoint did not allow a certain kind of file Type. So i had to do a workaround. So what you can try is to Zip your *.xlam File and Put that on the Sharepoint. Then you download it with the Code you already have. And then you just unzipped with the Following Code.
Sub Unzip1()
Dim FSO As Object
Dim oApp As Object
Dim Fname As Variant
Dim FileNameFolder As Variant
Dim DefPath As String
Dim strDate As String
Fname = strSavePath' I assume that this is the Path to the File you Downloaded
If Fname = False Then
'Do nothing
Else
'Root folder for the new folder.
DefPath = Application.DefaultFilePath 'Or Change it to the Path you want to unzip the Files
If Right(DefPath, 1) <> "\" Then
DefPath = DefPath & "\"
End If
'Create the folder name
strDate = Format(Now, " dd-mm-yy h-mm-ss")
FileNameFolder = DefPath & "MyUnzipFolder " & strDate & "\"
'Make the normal folder in DefPath
MkDir FileNameFolder
'Extract the files into the newly created folder
Set oApp = CreateObject("Shell.Application")
oApp.Namespace(FileNameFolder).CopyHere oApp.Namespace(Fname).items
'If you want to extract only one file you can use this:
'oApp.Namespace(FileNameFolder).CopyHere _
'oApp.Namespace(Fname).items.Item("test.txt")
MsgBox "You find the files here: " & FileNameFolder
On Error Resume Next
Set FSO = CreateObject("scripting.filesystemobject")
FSO.deletefolder Environ("Temp") & "\Temporary Directory*", True
End If
End Sub
And after that you just executed the Extension.
I Hope this can help you.
I could not find a way to download to add-ins, tried multiple different way and concluded that there was som authorization error or something else caused by the version of SharePoint I was using. The solution I found that suited my needs was to open the add-ins directly from SharePoint using this code:
On Error Resume Next
ActiveWorkbook.FollowHyperlink Address:="strUrl"
On Error GoTo 0

Creating Excel Macro for Exporting XML to a certain folder

I need to create a macro (which I have never done before) and if you guys can guide me to a right path, it would be really appreciated.
What I'm doing currently:
I have created a mapping XML which I have imported into Excel. Once it is imported into Excel, users will then go ahead and paste some data in it and export it to receive an XML data file, which then user can drop it to a FTP where the job picks it up and imports it into database.
Here's the problem:
The export has following node, which I do not want:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
Instead I want to replace it with following:
<?xml version="1.0" ?>
<Root xmlns="http://tempuri.org/CourseImport.xsd">
How do I automate this? Is there some kind of setting in Excel that could make it happen?
Basically, I want the export to have my root instead of the default root and I want to automatically be able to drop the file to specified path: example: \development\school\course import
Thanks!
My co-worker actually helped me out with this. I thought I should share what I did
Sub ExportXML()
'
' Export XML Macro exports the data that is in Excel to XML.
'
Const ForReading = 1
Const ForWriting = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
'
newFileName = Application.GetSaveAsFilename("out.xml", "XML Files (*.xml), *.xmls")
If newFileName = False Then
Exit Sub
End If
If objFSO.FileExists(newFileName) Then
objFSO.DeleteFile (newFileName)
End If
ActiveWorkbook.XmlMaps("Root_Map").Export URL:=newFileName
Set objFile = objFSO.OpenTextFile(newFileName, ForReading)
Dim count
count = 0
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
If count = 0 Then
strNewContents = strNewContents & "<?xml version=""1.0"" ?>" & vbCrLf
ElseIf count = 1 Then
strNewContents = strNewContents & "<Root xmlns=""http://tempuri.org/import.xsd"">" & vbCrLf
Else
strNewContents = strNewContents & strLine & vbCrLf
End If
count = count + 1
Loop
objFile.Close
Set objFile = objFSO.OpenTextFile(newFileName, ForWriting)
objFile.Write strNewContents
objFile.Close
End Sub

Resources