XML uitlezen met VBS-script

Pagina: 1
Acties:

Onderwerpen

Vraag


Acties:
  • 0 Henk 'm!

  • willu
  • Registratie: April 2016
  • Laatst online: 06-04-2016
Met VBS wil ik een XML bestand inlezen. Hoe ik dit moet inlezen is geen probleem.

De gewone nodes lees ik uit door naar de betreffende node te gaan
Bijv.
<mproxyMessage xmlns:ns2="com.cmp.mproxy.message" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:mproxyMessage">
<attachments>
<attachment>
<uri>C:\Users\administrator\AppData\Local\Medibridge\ </attachment>
</attachments>
</mproxyMessage>

lees ik uit met volgende regels

"Set colNodes=xmlDoc.selectNodes _
("//mproxyMessage/attachments/attachment/uri")
For Each objNode In colNodes
RapportBestandsLocatie = objNode.Text
Next"

Problemen met uitlezen heb ik echter met volgende nodes

<mproxyMessage xmlns:ns2="com.cmp.mproxy.message" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:mproxyMessage">
<option>
<map>
<element>
<key>FunctionalType</key>
<value>DMA-REP</value>
</element>
<element>
<key>HC-MESSAGE</key>
<value>true</value>
</element>
<element>
<key>CM-RecipientIDType</key>
<value>nihii</value>
</element>
<element>
<key>HC-RecipientMainIdentifier</key>
<value>71071702</value>
</element>
<element>
<key>HC-BodyFilename</key>
<value>body.txt</value>
</element>
<element>
<key>CM-RecipientID</key>
<value>17172562</value>
</element>
</map>
</option>
</mproxyMessage>

Je ziet dat er per element telkens een andere key met een andere value staat. Hoe kan ik naar een bepaalde key gaan, bijv "CM-RecipientID" en binnen dit element de value , in dit geval waarde "17172562" uitlezen.

[ Voor 2% gewijzigd door willu op 05-04-2016 15:10 . Reden: privacyschending ]

Alle reacties


Acties:
  • 0 Henk 'm!

  • PublishedMeteor
  • Registratie: Juli 2011
  • Laatst online: 16:21
Ik programmeer zelf geen VBS maar ik zal het in pseudo code plaatsen. Volgensmij kun je het beste gewoon over alle <element>'s itereren en dan kijken welke key er in dat element zit. Als deze key klopt met wat je wil ophalen dan vraag je de bijbehorende value op.
code:
1
2
3
4
5
for(int i = 0; i < elements.length; i++) {
    if(elements[i].key == "HC-BodyFilename") {
        return elements[i].value;
    }
}


Ik hoop dat het hiermee een beetje duidelijk is! Good luck!

Acties:
  • 0 Henk 'm!

  • Flythe
  • Registratie: Augustus 2006
  • Niet online
Het lijkt er op dat je op zoek bent naar sibling nodes met xPath.

Je kan een specifiek <element> selecteren aan de hand van de waarde die in de <key> staat, iets als: //element[key/text() = "whatever"]. Vervolgens kan je daar de value node van pakken.

Zie ook dit antwoord op SO.

Acties:
  • 0 Henk 'm!

  • Marco1994
  • Registratie: Juli 2012
  • Laatst online: 17:16
PublishedMeteor schreef op maandag 04 april 2016 @ 14:03:
Ik programmeer zelf geen VBS maar ik zal het in pseudo code plaatsen. Volgensmij kun je het beste gewoon over alle <element>'s itereren en dan kijken welke key er in dat element zit. Als deze key klopt met wat je wil ophalen dan vraag je de bijbehorende value op.
code:
1
2
3
4
5
for(int i = 0; i < elements.length; i++) {
    if(elements[i].key == "HC-BodyFilename") {
        return elements[i].value;
    }
}


Ik hoop dat het hiermee een beetje duidelijk is! Good luck!
Even offtopic, maar dit is wel een erg smerige manier om een value bij een key te zoeken. Bij een kleine array als dit zal het geen probleem vormen. Maar als je een grotere array hebt wil je dit soort zaken vermeiden.

Acties:
  • 0 Henk 'm!

  • PublishedMeteor
  • Registratie: Juli 2011
  • Laatst online: 16:21
Marco1994 schreef op maandag 04 april 2016 @ 17:54:
[...]


Even offtopic, maar dit is wel een erg smerige manier om een value bij een key te zoeken. Bij een kleine array als dit zal het geen probleem vormen. Maar als je een grotere array hebt wil je dit soort zaken vermeiden.
Uiteraard heb je hier helemaal gelijk in. Dit is totaal niet efficiënt, maar gezien het kleine stukje XML dat hij als voorbeeld gaf voorzie ik hier geen probleem. Uiteraard ken ik niet de hele casus waar dit probleem zich voordoet.

[ Voor 33% gewijzigd door PublishedMeteor op 05-04-2016 08:52 . Reden: Double content ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:54

Janoz

Moderator Devschuur®

!litemod

Marco1994 schreef op maandag 04 april 2016 @ 17:54:
Even offtopic, maar dit is wel een erg smerige manier om een value bij een key te zoeken. Bij een kleine array als dit zal het geen probleem vormen. Maar als je een grotere array hebt wil je dit soort zaken vermeiden.
Tja, en hoe zou het anders moeten? Als je maar 1 keer iets zoekt is deze manier nog altijd sneller dan het opbouwen van een efficient doorzoekbare datastructuur.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Marco1994
  • Registratie: Juli 2012
  • Laatst online: 17:16
Janoz schreef op dinsdag 05 april 2016 @ 10:16:
[...]

Tja, en hoe zou het anders moeten? Als je maar 1 keer iets zoekt is deze manier nog altijd sneller dan het opbouwen van een efficient doorzoekbare datastructuur.
Daarom zeg ik ook dat het bij een kleine dataset als dit geen probleem zal vormen. Daarbij ken ik de taal niet, maar ik kan me voorstellen dat er iets als een hashmap en een get methode bestaat.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:54

Janoz

Moderator Devschuur®

!litemod

Marco1994 schreef op dinsdag 05 april 2016 @ 11:15:
[...]

Daarom zeg ik ook dat het bij een kleine dataset als dit geen probleem zal vormen. Daarbij ken ik de taal niet, maar ik kan me voorstellen dat er iets als een hashmap en een get methode bestaat.
En hoe zou die hashmap gevuld gaan worden denk je?

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Marco1994
  • Registratie: Juli 2012
  • Laatst online: 17:16
Janoz schreef op dinsdag 05 april 2016 @ 12:07:
[...]

En hoe zou die hashmap gevuld gaan worden denk je?
Die hashmap zou waarschijnlijk soortgelijks (o (n)) gevuld worden maar de values eruit halen gaat dan wel veel efficiënter. Ik ben het met je eens dat dit voor deze casus niet the way to go is (zoals de ts hem beschrijft) maar voor een (veel) grotere casus denk ik wel de voorkeur heeft in mijn opinie

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:54

Janoz

Moderator Devschuur®

!litemod

Maar als je maar 1 value nodig hebt dan kost gewoon door de lijst itereren gemiddeld de helft van de tijd, ook bij zeer grote lijsten.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Marco1994
  • Registratie: Juli 2012
  • Laatst online: 17:16
Janoz schreef op dinsdag 05 april 2016 @ 12:19:
Maar als je maar 1 value nodig hebt dan kost gewoon door de lijst itereren gemiddeld de helft van de tijd, ook bij zeer grote lijsten.
Dat ben ik met je eens, dat zeg ik toch ook?

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:54

Janoz

Moderator Devschuur®

!litemod

Je hamerde op het feit dat het een kleine dataset is, maar dat is helemaal niet relevant. De aangeboden oplossing is waarschijnlijk de meest efficiente aangezien er maar 1 waarde opgehaald wordt. Daarbij maakt het helemaal niet uit of het een grote of kleine set is. Je geeft aan dat een map datastructuur uitlezen efficienter is. Dat is zeker zo, maar die dataset moet wel gevuld worden. EN dat kost ook tijd. Die bestaat niet zomaar. Sterker nog, zelfs als je van te voren weet welke 4 waarden je op moet halen, dan is gewoon de set doorlopen waarschijnlijk maar 75% van de tijd van het maken van een hashset.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • +1 Henk 'm!

  • Marco1994
  • Registratie: Juli 2012
  • Laatst online: 17:16
Janoz schreef op dinsdag 05 april 2016 @ 13:27:
Je hamerde op het feit dat het een kleine dataset is, maar dat is helemaal niet relevant. De aangeboden oplossing is waarschijnlijk de meest efficiente aangezien er maar 1 waarde opgehaald wordt. Daarbij maakt het helemaal niet uit of het een grote of kleine set is. Je geeft aan dat een map datastructuur uitlezen efficienter is. Dat is zeker zo, maar die dataset moet wel gevuld worden. EN dat kost ook tijd. Die bestaat niet zomaar. Sterker nog, zelfs als je van te voren weet welke 4 waarden je op moet halen, dan is gewoon de set doorlopen waarschijnlijk maar 75% van de tijd van het maken van een hashset.
Daar heb je opzicht wel een punt, ik onderschatte het vullen van de map. Vind dit toch wel interessante materie. Hoe eigenwijs (onterecht ;) ) ik ben, ga ik het een keer uittesten. Dank voor je insteek

Acties:
  • 0 Henk 'm!

  • JerX
  • Registratie: Mei 2006
  • Laatst online: 08-09 09:28
Lijkt me sowieso wijs om even fictieve locaties te gebruiken i.p.v. je werk bij het lokale ziekenhuis.. misschien kan een modje het knippen?

[ Voor 2% gewijzigd door JerX op 05-04-2016 15:12 . Reden: Zo te zien aangepast :) ]

Steam: Jerx | PSN: Jerxy88 | Xbox: Jerxy


Acties:
  • 0 Henk 'm!

  • willu
  • Registratie: April 2016
  • Laatst online: 06-04-2016
Bij deze heb ik de gegevens aangepast, goed opgemerkt.
De discussie is theoretisch interessant, maar hoe krijg ik het praktisch voor mekaar in VBScript

Acties:
  • 0 Henk 'm!

  • PublishedMeteor
  • Registratie: Juli 2011
  • Laatst online: 16:21
Als je weet hoe wat standaard dingen als een if-statement werken in je code, dan heb je aan deze stackoverflow link wel voldoende denk ik.

Iets als dit zou dan ongeveer moeten werken:
code:
1
2
3
4
5
6
7
8
9
"Set colNodes=xmlDoc.selectNodes _
("//mproxyMessage/option/map/element")
For Each objNode In colNodes
    SET key = objNode.getElementsByTagName("key")(0)
    // Hier je if-statement om te kijken of je deze key zoekt

    // Als de if klopt haal je zo de value op dan
    SET value = objNode.getElementsByTagName("value")(0)
Next"


Maar nogmaals programmeer ik geen VBA en heel eerlijk gezegd lijkt me dit niet de moeilijkste kwestie om op te lossen. Mocht je beginnend programmeur zijn, probeer dan gewoon enkele mogelijkheden ;)

Acties:
  • 0 Henk 'm!

  • willu
  • Registratie: April 2016
  • Laatst online: 06-04-2016
Bedankt allemaal, met de informatie wat ik van jullie gekregen heb en nog wat probeerwerk heb ik het met volgende statements kunnen oplossen

Set colNodes=xmlDoc.selectNodes _
("//mproxyMessage/option/map/element")

For Each objNode In colNodes
Set colNodes2 = objNode.childNodes
for each objNode2 in colNodes2
If ValueOK Then
If objNode2.nodeName = "value" Then
ValueOK = False
MsgBox objNode2.nodeName + " " + objNode2.firstChild.nodeValue
End if
End if
If objNode2.nodeName = "key" And objNode2.firstChild.nodeValue = "CM-RecipientID" Then
ValueOK = True
MsgBox objNode2.nodeName + " " + objNode2.firstChild.nodeValue
End if
next
Next

Acties:
  • 0 Henk 'm!

  • Killah_Priest
  • Registratie: Augustus 2001
  • Laatst online: 11:46
Ik zou de TS ook aanbevelen om ipv VBS over te gaan naar Powershell voor dit soort snelle scriptzaken ivm een goede ingebouwde xml ondersteuning en de eventuele vele makkelijk te vinden scripts (en powershell is toch wel de toekomst qua windows scripten vergeleken met vbs en batch)

[ Voor 48% gewijzigd door Killah_Priest op 07-04-2016 01:48 ]

Pagina: 1