alfabravo
Goto Top

XML auslesen mit VBScript: getElementsByTagName mit Platzhalter bzw. Wildcard möglich?

Hallo,

ich möchte einige Knoten aus einer XML-Datei in eine *.csv-Datei schreiben und komme an einer Stelle nicht weiter.

Die XML-Datei (Daten.xml) sieht so aus:

<?xml version="1.0" encoding="UTF-8"?>  
<ds5:Daten>
<ds2:Datensatz>
<ds2:Kundennummer>12345678</ds2:Kundennummer>
<ds2:Name>Mustermann</ds2:Name>
<ds2:Vorname>Max</ds2:Vorname>
</ds2:Datensatz>
<ds2:Datensatz>
<ds2:Kundennummer>10000000</ds2:Kundennummer>
<ds2:Name>Mustermann</ds2:Name>
<ds2:Vorname>Marlene</ds2:Vorname>
</ds2:Datensatz>
<ds2:Datensatz>
<ds2:Kundennummer>20000000</ds2:Kundennummer>
<ds2:Name>Testmann</ds2:Name>
<ds2:Vorname>Fritz</ds2:Vorname>
<ds2:Wohnort>Musterstadt</ds2:Wohnort>
</ds2:Datensatz>
</ds5:Daten>

Mit diesem Code gelingt das Auslesen und Schreiben in die Datei "Daten.csv" zunächst einmal:

Dim xmlDoc, objNodeList, objFSO, objFile, Quelle, Ziel, Elem

Quelle = "Daten.xml"  
Ziel = "Daten.csv"  

Set objFSO = Wscript.CreateObject("Scripting.FileSystemObject")  
Set objFile = objFSO.OpenTextFile(Ziel, ForWriting, Create)

Const ForWriting = 2
Const Create = true

Set xmlDoc = CreateObject("Microsoft.XMLDOM")  

xmlDoc.load(Quelle)

Set objNodeList = xmlDoc.documentElement.childNodes

For Each Elem In objNodeList

   SET Kundennummer = Elem.getElementsByTagName("ds2:Kundennummer")(0)  
   SET Name = Elem.getElementsByTagName("ds2:Name")(0)  
   SET Vorname = Elem.getElementsByTagName("ds2:Vorname")(0)  

   If Elem.getElementsByTagName("ds2:Kundennummer")(0) Is Nothing Then Kundennummer = "" Else Kundennummer = Kundennummer.text  
   If Elem.getElementsByTagName("ds2:Name")(0) Is Nothing Then Name = "" Else Name = Name.text  
   If Elem.getElementsByTagName("ds2:Vorname")(0) Is Nothing Then Vorname = "" Else Vorname = Vorname.text  

   objFile.WriteLine Kundennummer & ";" & Name & ";" & Vorname  

Next

Set xmlDoc = Nothing
Set objNodeList = Nothing
Set objFSO = Nothing
Set objFile = Nothing
Set Quelle = Nothing
Set Ziel = Nothing
Set Elem = Nothing

Das Problem bei der Sache ist, dass die ersten drei Stelle der Knotennamen von Quelldatei zu Quelldatei variieren können. Das heißt, statt

ds2:Kundennummer
ds2:Name
ds2:Vorname

könnten die Knoten auch

ds5:Kundennummer
ds5:Name
ds5:Vorname

heißen.

Ist es möglich, in
SET Kundennummer = Elem.getElementsByTagName("ds2:Kundennummer")(0)  
statt des "ds2:" in "ds2:Kundennummer" einen Platzhalter zu verwenden?

Bisher ist es mir -leider- nicht gelungen, das hinzubekommen ;-(

Hat jemand von Euch eine Lösung?

Content-Key: 265700

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

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

Member: emeriks
emeriks Mar 09, 2015 updated at 13:34:43 (UTC)
Goto Top
Hi,
Du könntest entweder die ChildElements durchlaufen und einzeln auswerten oder das File zunächst als Text öffnen, diesen Präfix bestimmen, und dann erst über XMLDOM auswerten.

E.
Member: colinardo
Solution colinardo Mar 09, 2015, updated at Mar 13, 2015 at 18:57:27 (UTC)
Goto Top
Hallo Alfabravo,
dein XML scheint mir nicht valide da die Namespace-Deklarationen für die Namespace Prefixes ds2 und ds5 fehlen, oder hast du die fürs Forum weg gelassen ?
Die sehen z.B. so aus:
xmlns:ds5="http://www.domain.net" xmlns:ds2="http://www.domain.net"
Wenn diese vorhanden wären ginge dein gewünschtes Verhalten z.B. so mit einer XPath-Query:
(ohne Namespace-Deklaration spielt das XMLDOM-Object hier leider nicht mit)
Set xml = CreateObject("Msxml2.DOMDocument.6.0")  
xml.async = False
xml.load("C:\temp\daten.xml")  
Set nodes = xml.selectNodes("//*[substring(name(), string-length(name()) - 11) = 'Kundennummer']")  
For Each node In nodes
	strKundennr = node.text
	strName = node.parentNode.selectSingleNode("*[substring(name(), string-length(name()) - 3) = 'Name']").text  
	strVorname = node.parentNode.selectSingleNode("*[substring(name(), string-length(name()) - 6) = 'Vorname']").text  
	MsgBox strKundennr & ";" & strName & ";" & strVorname  
Next
Grüße Uwe
Member: alfabravo
alfabravo Mar 09, 2015 updated at 18:38:28 (UTC)
Goto Top
Hallo Uwe, vielen Dank! Funktioniert auf das Beispiel angewandt wirklich super !

Ja, die "Daten.xml" war sehr vereinfacht dargestellt, der Übersichtlichkeit wegen. Sie ist noch etwas komplexer.

Und da tut sich leider mein nächstes Problem auf: Der Knoten <ds2:Datensatz> enthält noch eine weitere Ebene, die ich im Beispiel weggelassen hatte:

<?xml version="1.0" encoding="UTF-8"?>  
<ds5:Daten>
   <ds2:Datensatz>
      <ds2:KundenID>
         <ds2:Kundennummer>12345678</ds2:Kundennummer>
      </ds2:KundenID>
      <ds2:Kundendaten>
         <ds2:Name>Mustermann</ds2:Name>
         <ds2:Vorname>Max</ds2:Vorname>
      </ds2:Kundendaten>
   </ds2:Datensatz>
   <ds2:Datensatz>
      <ds2:KundenID>
         <ds2:Kundennummer>10000000</ds2:Kundennummer>
      </ds2:KundenID>
      <ds2:Kundendaten>
         <ds2:Name>Mustermann</ds2:Name>
         <ds2:Vorname>Marlene</ds2:Vorname>
      </ds2:Kundendaten>
   </ds2:Datensatz>
   <ds2:Datensatz>
      <ds2:KundenID>
         <ds2:Kundennummer>20000000</ds2:Kundennummer>
      </ds2:KundenID>
      <ds2:Kundendaten>
         <ds2:Name>Testmann</ds2:Name>
         <ds2:Vorname>Fritz</ds2:Vorname>
         <ds2:Wohnort>Musterstadt</ds2:Wohnort>
      </ds2:Kundendaten>
   </ds2:Datensatz>
</ds5:Daten>

Jetzt komme ich mit Deiner Methode leider von <ds2:KundenID> aus nicht in den Nachbarknoten <ds2:Kundendaten>, in dem weitere Nutzdaten stehen. Ich müsste aus <ds2:Datensatz> also quasi die genannten "Kindeskinder" auslesen - laienhaft ausgedrückt...
Member: colinardo
colinardo Mar 09, 2015 updated at 18:46:15 (UTC)
Goto Top
Das geht ziemlich simpel mit der Eigenschaft parentNode. Damit wechselst du einfach zwei Knoten höher und lässt XPath von dort aus suchen ...
strName = node.parentNode.parentNode.selectSingleNode("*[substring(name(), string-length(name()) - 3) = 'Name']").text   
Member: Dschainers
Dschainers Oct 12, 2015 at 09:48:20 (UTC)
Goto Top
Hallo,
ich habe hier ein ZUGFERD XML Datei, die will ich mit obigen Mitteln auslesen, leider bekomme ich immer einen Fehler wenn ich "node.parentNode.select..." aufrufen will.
hier die ersten Zeilen der zugferd xml datei:
<rsm:CrossIndustryDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rsm="urn:ferd:CrossIndustryDocument:invoice:1p0" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:12" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:15">  
	<rsm:SpecifiedExchangedDocumentContext>
		<ram:TestIndicator><udt:Indicator>true</udt:Indicator></ram:TestIndicator><!-- Im Echtbetrieb muss der TestIndicator entweder vollständig entfallen oder auf false stehen. -->
		<ram:GuidelineSpecifiedDocumentContextParameter>
			<ram:ID>urn:ferd:CrossIndustryDocument:invoice:1p0:extended</ram:ID>
		</ram:GuidelineSpecifiedDocumentContextParameter>
	</rsm:SpecifiedExchangedDocumentContext>
	<rsm:HeaderExchangedDocument>
		<ram:ID>KR87654321012</ram:ID>
		<ram:Name>KOSTENRECHNUNG</ram:Name>
		<ram:TypeCode>380</ram:TypeCode>
		<ram:IssueDateTime>
			<udt:DateTimeString format="102">20131006</udt:DateTimeString>  
		</ram:IssueDateTime>
		<ram:IncludedNote>
			<ram:ContentCode>ST3</ram:ContentCode>
			<ram:Content>Es bestehen Rabatt- oder Bonusvereinbarungen.</ram:Content>
			<ram:SubjectCode>AAK</ram:SubjectCode>
		</ram:IncludedNote>
		<ram:IncludedNote>
			<ram:ContentCode>EEV</ram:ContentCode>
			<ram:Content>Der Verkäufer bleibt Eigentümer der Waren bis zur vollständigen Erfüllung der Kaufpreisforderung.</ram:Content>
			<ram:SubjectCode>AAJ</ram:SubjectCode>
		</ram:IncludedNote>
		<ram:IncludedNote>
			<ram:Content>MUSTERLIEFERANT GMBH
BAHNHOFSTRASSE 99
99199 MUSTERHAUSEN
Geschäftsführung:
Max Mustermann
USt-IdNr: DE123456789
Telefon: +49 932 431 0
www.musterlieferant.de
HRB Nr. 372876
Amtsgericht Musterstadt
GLN 4304171000002</ram:Content>
			<ram:SubjectCode>REG</ram:SubjectCode>
		</ram:IncludedNote>
	</rsm:HeaderExchangedDocument>
	<rsm:SpecifiedSupplyChainTradeTransaction>
		<ram:ApplicableSupplyChainTradeAgreement>
			<ram:SellerTradeParty>
				<ram:ID>549910</ram:ID>
				<ram:GlobalID schemeID="0088">4333741000005</ram:GlobalID>  
				<ram:Name>MUSTERLIEFERANT GMBH</ram:Name>
				<ram:DefinedTradeContact>
					<ram:TelephoneUniversalCommunication>
						<ram:CompleteNumber>+49 932 431 500</ram:CompleteNumber>
					</ram:TelephoneUniversalCommunication>
					<ram:EmailURIUniversalCommunication>
						<ram:URIID>max.mustermann@musterlieferant.de</ram:URIID>
					</ram:EmailURIUniversalCommunication>
				</ram:DefinedTradeContact>
				<ram:PostalTradeAddress>
					<ram:PostcodeCode>99199</ram:PostcodeCode>
					<ram:LineOne>BAHNHOFSTRASSE 99</ram:LineOne>
					<ram:CityName>MUSTERHAUSEN</ram:CityName>
					<ram:CountryID>DE</ram:CountryID>
				</ram:PostalTradeAddress>
				<ram:SpecifiedTaxRegistration>
					<ram:ID schemeID="FC">5133081508159</ram:ID>  
				</ram:SpecifiedTaxRegistration>
			</ram:SellerTradeParty>
			<ram:BuyerTradeParty>
				<ram:ID>339420</ram:ID>
		
Member: Dschainers
Dschainers Oct 12, 2015 at 09:49:22 (UTC)
Goto Top
jetzt noch die VBS Datei:
Option explicit



Dim xml, nodes, node, testind, ID, Name, PLZ, Adresse


Set xml = CreateObject("Msxml2.DOMDocument.6.0")  

xml.async = False


xml.load("Basic_Einfach.xml")  


Set nodes = xml.selectNodes("//*[substring(name(), string-length(name()) - 15) = 'SellerTradeParty']")  
WScript.Echo(nodes.length)
For Each node In nodes


ID = ""  
Name = ""  
PLZ = ""  
Adresse = ""  



ID = node.selectSingleNode("*[substring(name(), string-length(name()) - 1) = 'ID']").text  

MsgBox ID

Name = node.selectSingleNode("*[substring(name(), string-length(name()) - 3) = 'Name']").text  

MsgBox Name

Adresse = node.selectSingleNode("*[substring(name(), string-length(name()) - 17) = 'PostalTradeAddress']").text  

MsgBox Adresse

plz = node.parentNode.selectSingleNode("*[substring(name(), string-length(name()) - 17) = 'PostcodeCode']").text  

MsgBox PLZ



testind = node.text
MsgBox testind


Next
Member: Dschainers
Dschainers Oct 12, 2015 at 09:50:23 (UTC)
Goto Top
Der Fehler tritt bei "plz = node.parentNode.sele...." auf.

Kann mir jemand helfen, ich bin verzweifelt.

Vielen Dank
Dschainers
Member: colinardo
colinardo Oct 14, 2015 updated at 08:10:38 (UTC)
Goto Top
Guten Morgen Dschainers,
danke für deine Nachrichtflut face-wink, aber auch wir haben Arbeit, stehen also nicht zu jeder Zeit Live zur Verfügung.

Für deine XML sähe der Code hier so aus:
Set xml = CreateObject("Msxml2.DOMDocument.6.0")  
xml.async = False
xml.load("C:\temp\daten.xml")  
xml.setProperty "SelectionLanguage", "XPath"  
xml.setProperty "SelectionNamespaces","xmlns:ram='urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:12'"  

Set nodes = xml.selectNodes("//ram:SellerTradeParty")  
For Each node In nodes
	strID = node.selectSingleNode("ram:ID").text  
	strName = node.selectSingleNode("ram:Name").text  
	strPLZ = node.selectSingleNode("ram:PostalTradeAddress/ram:PostcodeCode").text  
	strAdresse = node.selectSingleNode("ram:PostalTradeAddress/ram:LineOne").text  
	strCityName = node.selectSingleNode("ram:PostalTradeAddress/ram:CityName").text  
	strCountry = node.selectSingleNode("ram:PostalTradeAddress/ram:CountryID").text  
	
	MsgBox "ID: " & strID & vbNewLine & _  
			"Name: " & strName & vbNewLine & _  
			"PLZ: " & strPLZ & vbNewLine & _  
			"Adresse: " & strAdresse & vbNewLine & _  
			"Stadt: " & strCityName & vbNewLine & _  
			"Land: " & strCountry  
Next
Schönen Urlaub face-smile
Grüße Uwe
Member: Dschainers
Dschainers Oct 14, 2015 at 08:42:23 (UTC)
Goto Top
Vielen Dank, ich werde mich mal daran versuchen. Melde mich wieder.
Dschainers
Member: Dschainers
Dschainers Oct 14, 2015 at 09:04:20 (UTC)
Goto Top
Hallo Colinardo (Uwe),

super hat alles funktioniert!!
Nochmals Entschuldigung, für die Nachrichtenflut, ich versuch mich zu bessern.
Ich geh jetzt erst mal in Urlaub.
Vielen Dank.
Dschainers
Member: colinardo
colinardo Oct 14, 2015 updated at 09:08:21 (UTC)
Goto Top
Zitat von @Dschainers:
super hat alles funktioniert!!
Schön. face-smile
Nochmals Entschuldigung, für die Nachrichtenflut, ich versuch mich zu bessern.
Schon in Ordnung..
Ich geh jetzt erst mal in Urlaub.
Dann wünsche ich hoffentlich viel Sonne, hier hat's heute Schnee <X-) Jo is denn heut scho Weihnachten