Avatar billede stalle Nybegynder
10. november 2008 - 21:20 Der er 12 kommentarer og
1 løsning

Problem med at få værdier vha VBS

Jeg har nedenstående struktur, men synes ikke jeg kan få det til at virke.
Set Nodtriggerrecords = Xdoc.documentelement.selectsinglenode("/Triggertags/triggertag[@name='Maksimum temperature R10000 1']/Triggerrecords/triggerrecord")

Jeg får at vide: "Object required"
Jeg har prøvet at skrive strengen ud, for at tjekke at det ser rigtigt ud. Det gør det, men alligevel vil det ikke virke for mig.

Strukturen er:
<triggertags>
    <triggertag name="Maksimum temperature R10000 1" remark="" unit="C" decimals="0" logarithm="0" lower_limit="0.000000" upper_limit="0.000000"/>
        <triggerrecords>
            <triggerrecord time="2008-10-26T01:07:08.260" counter="1" value="133" flags="65536"/>
        </triggerrecords>
    <triggertag name="Maksimum temperature R10000 2" remark="" unit="C" decimals="0" logarithm="0" lower_limit="0.000000" upper_limit="0.000000"/>
        <triggerrecords>
            <triggerrecord time="2008-10-26T01:07:08.260" counter="1" value="142" flags="65536"/>
        </triggerrecords>
    <triggertag name="R10000 1 100 procent" remark="" unit="%" decimals="0" logarithm="0" lower_limit="0.000000" upper_limit="0.000000"/>
        <triggerrecords>
            <triggerrecord time="2008-10-26T01:07:08.260" counter="1" value="465" flags="65536"/>
        </triggerrecords>
</triggertags>

Det jeg gerne vil have fat på, er "time" og "value" fra:
<triggerrecord time="2008-10-26T01:07:08.260" counter="1" value="465" flags="65536"/>

Skulle jeg have forklaret mig for "svagt" må i endelig sige til.
Avatar billede arne_v Ekspert
11. november 2008 - 04:43 #1
Set doc = CreateObject("Microsoft.XMLDOM")
doc.Async = False
doc.Load("trigger.xml")
Set ttag = doc.SelectSingleNode("//triggertags/triggertag[@name='Maksimum temperature R10000 1']")
Set trrecs = ttag.NextSibling
t = trrecs.SelectSingleNode("//triggerrecords/triggerrecord/@time").Text
v = trrecs.SelectSingleNode("//triggerrecords/triggerrecord/@value").Text
WScript.Echo t & " " & v
Set trrecs = Nothing
Set ttag = Nothing
Set doc = Nothing
Avatar billede softspot Forsker
11. november 2008 - 08:49 #2
Hvilken linie fejler den i (hvad står der i linien)? Du skal sikre dig at xdoc er initieret. Hvis din XPath ikke returnere noget burde den objektvariabel du tildeler noden blot indeholde nothing og ikke give en runtimefejl.

Du burde kunne bruge den XPath du angiver, dog skal du være opmærksom på at node-tags er case sensitive, så Triggerrecords og triggerrecords er IKKE det samme!

Du burdu kunne gøre dette:

Set Nodtriggerrecords = Xdoc.documentelement.selectsinglenode("/triggertags/triggertag[@name='Maksimum temperature R10000 1']/triggerrecords/triggerrecord")
if not Nodtriggerrecords is nothing then
  sTime = Nodtriggerrecords.getAttribute("time")
  sValue = Nodtriggerrecords.getAttribute("value")
  WScript.Echo sTime & ": " & sValue
else
  WScript.Echo "Elementet findes ikke."
end if

En anden ting du skal være opmærksom på er, at dobbelt skråstreg (//) søger i hele strukturen efter triggertags, hvilket kan have indflydelse på performance i en stor struktur, så hvis du kan referere nodes absolut eller relativt, er det bedre for performance.
Avatar billede stalle Nybegynder
11. november 2008 - 11:16 #3
arne_v
Din løsning giver mig nogle værdier, men desværre kun for den første entry.
Altså indeholder min "value" 133 for alle records.

softspot
Den metode du skriver, var faktisk det jeg prøvede i førete omgang.
At der er er sneget sig et stort T ind er en tastebørge, og ikke årsagen.

Jeg prøver lige og vise jer hele baduljen:

set objOutputFileMes = objFileSys.CreateTextFile(exportFileNameMes,TRUE)
set nodTriggerGroups = xdoc.documentelement.selectnodes("/batch/snapshot/triggers/trigger/triggergroups/triggergroup")

'Writes header in file'
objOutputFileMes.Writeline(CreateHeader(ID))
objOutputFileMes.WRITELINE("Name,Type,LSL,USL,Actual,Time")

for each nodTriggerGroup in nodTriggerGroups
    TriggerGroupName = nodTriggerGroup.getattribute("name")
    'objOutputFileMes.Writeline(TriggerGroupName)
    set nodTriggerTags = xdoc.documentelement.selectnodes("/batch/snapshot/triggers/trigger/triggergroups/triggergroup[@name='" & TriggerGroupName & "']/triggertags/triggertag")

    for each nodTriggerTag in nodTriggerTags
        TriggerTagName = nodTriggerTag.getattribute("name")
        if not TriggerTagName = "" then
            TriggerUnit = nodTriggerTag.getattribute("unit")
            TriggerLSL = nodtriggertag.getattribute("lower_limit")
            TriggerUSL = nodtriggertag.getattribute("upper_limit")
            'TriggerDec = nodtriggertag.getattribute("decimals")'
            if TriggerLSL = 0 and TriggerUSL = 0 then
                TriggerLSL = ""
                TriggerUSL = ""
            'else
            '  TriggerLSL = Round(TriggerLSL,TriggerDec)
            '  TriggerUSL = Round(TriggerUSL,TriggerDec)
            end if
           
            Set nodTriggerRecords = xdoc.documentelement.selectsinglenode("/batch/snapshot/triggers/trigger/triggergroups/triggergroup[@name='" & Triggergroupname & "']/triggertags/triggertag[@name='" & TriggerTagName & "']/triggerrecords")
            TriggerActual = nodTriggerRecords.getAttribute("/triggerrecord/@value")
            TriggerTime = nodTriggerRecords.getAttribute("/triggerrecord/@time")
            wscript.echo "TriggerTagName er: " & TriggerTagName
            wscript.echo "Value : " & TriggerValue
            wscript.echo "Time : " & TriggerTime
           
            TriggerTime = Replace(TriggerTime,"T"," ")
            objOutputFileMes.writeline(TriggerTagName & "," & TriggerUnit & "," & TriggerLSL & "," & TriggerUSL & "," & TriggerActual & "," & TriggerTime)
            TriggerActual = ""
            TriggerTime =""
        end if
    next
next

XML:
<batch name="8097" starttime="2008-10-25T19:59:10.243" starttimeflag="0" endtime="2008-10-26T01:07:11.025"  endtimeflag="0" batchstate="40" >
    <snapshot>
        <triggers>
            <trigger name="Trigger" remark="">
                <triggergroups>
                    <triggergroup name="Laminat Temperature" >
                        <triggertags>
                            <triggertag name="Maksimum temperature R10000 1" remark="" unit="C" decimals="0" logarithm="0" lower_limit="0.000000" upper_limit="0.000000"/>
                                <triggerrecords>
                                    <triggerrecord time="2008-10-26T01:07:08.223" counter="1" value="133" flags="65536"/>
                                </triggerrecords>
                            <triggertag name="Maksimum temperature R10000 2" remark="" unit="C" decimals="0" logarithm="0" lower_limit="0.000000" upper_limit="0.000000"/>
                                <triggerrecords>
                                    <triggerrecord time="2008-10-26T01:07:08.232" counter="1" value="142" flags="65536"/>
                                </triggerrecords>
                            <triggertag name="R10000 1 100 procent" remark="" unit="%" decimals="0" logarithm="0" lower_limit="0.000000" upper_limit="0.000000"/>
                                <triggerrecords>
                                    <triggerrecord time="2008-10-26T01:07:08.260" counter="1" value="465" flags="65536"/>
                                </triggerrecords>
                            <triggertag name="R10000 1 over 100 C (Minimum 200 min)" remark="" unit="Min" decimals="0" logarithm="0" lower_limit="0.000000" upper_limit="0.000000"/>
                                <triggerrecords>
                                    <triggerrecord time="2008-10-26T01:07:08.260" counter="1" value="185" flags="65536"/>
                                </triggerrecords>
                            <triggertag name="R10000 1 over 105 C (Minimum 125 min)" remark="" unit="Min" decimals="0" logarithm="0" lower_limit="0.000000" upper_limit="0.000000"/>
                                <triggerrecords>
                                    <triggerrecord time="2008-10-26T01:07:08.260" counter="1" value="175" flags="65536"/>
                                </triggerrecords>
                            <triggertag name="R10000 1 over 110 C (Minimum 90 min)" remark="" unit="Min" decimals="0" logarithm="0" lower_limit="0.000000" upper_limit="0.000000"/>
                                <triggerrecords>
                                    <triggerrecord time="2008-10-26T01:07:08.260" counter="1" value="167" flags="65536"/>
                                </triggerrecords>
                            <triggertag name="R10000 1 over 115 C (Minimum 70 min)" remark="" unit="Min" decimals="0" logarithm="0" lower_limit="0.000000" upper_limit="0.000000"/>
                                <triggerrecords>
                                    <triggerrecord time="2008-10-26T01:07:08.260" counter="1" value="159" flags="65536"/>
                                </triggerrecords>
                            <triggertag name="R10000 1 over 120 C (Minimum 60 min)" remark="" unit="Min" decimals="0" logarithm="0" lower_limit="0.000000" upper_limit="0.000000"/>
                                <triggerrecords>
                                    <triggerrecord time="2008-10-26T01:07:08.260" counter="1" value="150" flags="65536"/>
                                </triggerrecords>
                            <triggertag name="R10000 2 100 procent" remark="" unit="%" decimals="0" logarithm="0" lower_limit="0.000000" upper_limit="0.000000"/>
                                <triggerrecords>
                                    <triggerrecord time="2008-10-26T01:07:08.260" counter="1" value="540" flags="65536"/>
                                </triggerrecords>
                            </triggertags>
                        </triggergroup>
                    </triggergroups>
                </trigger>
            </triggers>
        </snapshot>
    </batch>


Jeg ved det kan være RET forvirrende og se, men har da vist fået set mig blind på hvad der er galt

Hvor jeg bruger den del arne_v gav mig:

set objOutputFileMes = objFileSys.CreateTextFile(exportFileNameMes,TRUE)
set nodTriggerGroups = xdoc.documentelement.selectnodes("/batch/snapshot/triggers/trigger/triggergroups/triggergroup")

'Writes header in file'
objOutputFileMes.Writeline(CreateHeader(ID))
objOutputFileMes.WRITELINE("Name,Type,LSL,USL,Actual,Time")

for each nodTriggerGroup in nodTriggerGroups
    TriggerGroupName = nodTriggerGroup.getattribute("name")
    'objOutputFileMes.Writeline(TriggerGroupName)
    set nodTriggerTags = xdoc.documentelement.selectnodes("/batch/snapshot/triggers/trigger/triggergroups/triggergroup[@name='" & TriggerGroupName & "']/triggertags/triggertag")

    for each nodTriggerTag in nodTriggerTags
        TriggerTagName = nodTriggerTag.getattribute("name")
        if not TriggerTagName = "" then
            TriggerUnit = nodTriggerTag.getattribute("unit")
            TriggerLSL = nodtriggertag.getattribute("lower_limit")
            TriggerUSL = nodtriggertag.getattribute("upper_limit")
            'TriggerDec = nodtriggertag.getattribute("decimals")'
            if TriggerLSL = 0 and TriggerUSL = 0 then
                TriggerLSL = ""
                TriggerUSL = ""
            'else
            '  TriggerLSL = Round(TriggerLSL,TriggerDec)
            '  TriggerUSL = Round(TriggerUSL,TriggerDec)
            end if
           
            Set nodTriggerRecords = xdoc.documentelement.selectsinglenode("/batch/snapshot/triggers/trigger/triggergroups/triggergroup[@name='" & Triggergroupname & "']/triggertags/triggertag[@name='" & TriggerTagName & "']/triggerrecords")
            set nodTriggerRecordsNext = nodTriggerRecords.nextsibling
            TriggerActual = nodTriggerRecordsNext.selectsinglenode("//triggerrecords/triggerrecord/@value").Text
            TriggerTime = nodTriggerRecordsNext.selectsinglenode("//triggerrecords/triggerrecord/@time").Text
            wscript.echo "TriggerTagName er: " & TriggerTagName
            wscript.echo "Value : " & TriggerValue
            wscript.echo "Time : " & TriggerTime
           
            TriggerTime = Replace(TriggerTime,"T"," ")
            objOutputFileMes.writeline(TriggerTagName & "," & TriggerUnit & "," & TriggerLSL & "," & TriggerUSL & "," & TriggerActual & "," & TriggerTime)
            TriggerActual = ""
            TriggerTime =""
        end if
    next
next
Avatar billede stalle Nybegynder
11. november 2008 - 11:17 #4
Hov
med arne_v's ser linien:

Set nodTriggerRecords = xdoc.documentelement.selectsinglenode("/batch/snapshot/triggers/trigger/triggergroups/triggergroup[@name='" & Triggergroupname & "']/triggertags/triggertag[@name='" & TriggerTagName & "']/triggerrecords")

Sådan ud:

Set nodTriggerRecords = xdoc.documentelement.selectsinglenode("/batch/snapshot/triggers/trigger/triggergroups/triggergroup[@name='" & Triggergroupname & "']/triggertags/triggertag[@name='" & TriggerTagName & "']")
Avatar billede softspot Forsker
11. november 2008 - 11:44 #5
Denne passage:

    TriggerGroupName = nodTriggerGroup.getattribute("name")
    'objOutputFileMes.Writeline(TriggerGroupName)
    set nodTriggerTags = xdoc.documentelement.selectnodes("/batch/snapshot/triggers/trigger/triggergroups/triggergroup[@name='" & TriggerGroupName & "']/triggertags/triggertag")

    for each nodTriggerTag in nodTriggerTags

burde kunne rettes til:

    TriggerGroupName = nodTriggerGroup.getattribute("name")
    'objOutputFileMes.Writeline(TriggerGroupName)

    for each nodTriggerTag in nodTriggerGroup.selectNodes("triggertags/triggertag")

Der er ikke nogen grund til at lave et absolut opslag i XML-strukturen for at finde elementer under det element du allerede har fat i.

Denne passage:

            Set nodTriggerRecords = xdoc.documentelement.selectsinglenode("/batch/snapshot/triggers/trigger/triggergroups/triggergroup[@name='" & Triggergroupname & "']/triggertags/triggertag[@name='" & TriggerTagName & "']/triggerrecords")
            TriggerActual = nodTriggerRecords.getAttribute("/triggerrecord/@value")
            TriggerTime = nodTriggerRecords.getAttribute("/triggerrecord/@time")

skal umiddelbart ændres til:

            Set nodTriggerRecords = nodTriggerTag.selectSingleNode("triggerrecords/triggerrecord")
            TriggerActual = nodTriggerRecords.getAttribute("value")
            TriggerTime = nodTriggerRecords.getAttribute("time")


Denne version håndterer dog kun én triggerrecord inde i én triggerrecords
Avatar billede stalle Nybegynder
11. november 2008 - 14:03 #6
Hvis jeg kunne blive mere skaldet, blev jeg det nu.

softspot
Det er da lykkedes mig og få det meste til at virke.
Hvad angår time & value, har jeg ikke haft held til det med den metode du beskriver.

Set nodTriggerRecords = nodTriggerTag.selectSingleNode("triggerrecords/triggerrecord")
TriggerActual = nodTriggerRecords.getAttribute("value")
TriggerTime = nodTriggerRecords.getAttribute("time")

Giver mig den fejl jeg startede ud med.
bruger jeg "//triggerrecords/triggerrecord" Får jeg kun indholdet af den første record.
Manglende forståelse af hvordan XML-håndteres kan selvfølgelig skyldes mit manglende held.

Ligger i mon inde med ekstra fif?
Avatar billede softspot Forsker
11. november 2008 - 14:14 #7
Fordømt! Jeg havde ikke bemærket at triggerrecords ikke lå inde i triggertag-elementet, men i stedet er sidestillet med triggertag (det var indrykningen i XML-data der snød mig :-)).

Så skal jeg lige forstå hvad du har til hensigt, for der er umiddelbart ikke nogen garanteret orden i elementer i en XML-fil, så du kan ikke med sikkerhed forvente at det næste element efter et triggertag-element er et triggerrecords-element. Derfor skal der være noget som relaterer et triggerrecords-element til et triggertag-element for at du kan sikre den korrekte sammenhæng...
Avatar billede stalle Nybegynder
11. november 2008 - 14:28 #8
Det sker :)

Jeg ved med 99,9% sikkerhed, at strukturen altid ser ud som den gør i det jeg har  pasted.

Men kortfattet drejer det sig om at jeg skal have lavet en lilie for hvert triggertag
For eksempel skal:

<triggertag name="Maksimum temperature R10000 1" remark="" unit="C" decimals="0" logarithm="0" lower_limit="0.000000" upper_limit="0.000000"/>
        <triggerrecords>
            <triggerrecord time="2008-10-26T01:07:08.260" counter="1" value="133" flags="65536"/>
        </triggerrecords>
    <triggertag name="Maksimum temperature R10000 2" remark="" unit="C" decimals="0" logarithm="0" lower_limit="0.000000" upper_limit="0.000000"/>
        <triggerrecords>
            <triggerrecord time="2008-10-26T01:07:08.260" counter="1" value="142" flags="65536"/>
        </triggerrecords>


Ende med at se ud som:

Maksimum temperature R10000 1,C,0,0,133,2008-10-26T01:07:08.260
Maksimum temperature R10000 2,C,0,0,142,2008-10-26T01:07:08.260


Håber det giver en bedre idé om hvad jeg vil opnår.

Hidtil er det eneste der har drillet mig, det at få "time" og "value" hentet ud.
Avatar billede softspot Forsker
11. november 2008 - 14:43 #9
jamen, så kan du benytte nodTriggerTag.nextsibling til at finde det efterfølgende triggerrecords-element og derfra læse time og value på firstChild. I kort genvejsform sådan:

with nodTriggerTag.nextsibling.firstChild
  TriggerTime = .getAttribute("time")
  TriggerActual = .getAttribute("value")
end with

Dog er denne metode noget usikker, da du ikke lægger noget tjek ind for den situation, hvor nextsibling ikke eksisterer eller at firstChild på nextSibling ikke eksisterer for den sags skyld. Du kan dog sagtens splitte den op, så du kan tjekke om nextSibling er nothing inden du aflæser firstChild og så fremdeles... (en simpel if, hvis du skulle være i tvivl):

if not nodTriggerTag.nextsibling is nothing then
  if not nodTriggerTag.nextsibling.firstChild is nothing then
    with nodTriggerTag.nextsibling.firstChild
      TriggerTime = .getAttribute("time")
      TriggerActual = .getAttribute("value")
    end with
  end if
end if

Det skal så ind i stedet for dette kode:

            Set nodTriggerRecords = nodTriggerTag.selectSingleNode("triggerrecords/triggerrecord")
            TriggerActual = nodTriggerRecords.getAttribute("value")
            TriggerTime = nodTriggerRecords.getAttribute("time")
Avatar billede stalle Nybegynder
12. november 2008 - 08:03 #10
Excelent softspot!

Netop den sidste løsning gjorde udslaget!

Point goes to you !!
Avatar billede softspot Forsker
12. november 2008 - 08:33 #11
Velbekomme :)
Avatar billede stalle Nybegynder
12. november 2008 - 08:36 #12
Nu må jeg bare håbe, at jeg også begynder og fatte noget omkring det her XML.
Du kender ikke tilfældigvis en god side hvor der er en forklaring hvordan tingene hænger sammen ?
Avatar billede softspot Forsker
12. november 2008 - 08:47 #13
Hmm... det er vel ikke så meget XML som det er XPath der er udfordringen... eller hvad?

Jeg har selv lært noget ved at læse om XPath i et par bøger, samt bruge det i praksis, så mine primære opslag går mest ud på at få opfrisket de funktioner jeg kan bruge (der er nu ikke så mange endda). Derfor er mit opslagsværk mest baseret på MSDN og flg. links indeholder da noget om XML og XPath:

http://msdn.microsoft.com/en-us/library/aa286548.aspx
http://msdn.microsoft.com/en-us/library/aa153035.aspx
http://msdn.microsoft.com/en-us/library/bb985160.aspx

m.fl., men ligeså snart du får åbnet MSDN, kan du sagtens finde flere atikler og referencematerialer, hvis du kigger dig lidt omkring, eller bare søger...

Tak for point :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester