Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

help parsing a xml file

Status
Not open for further replies.

EgilHansen

IS-IT--Management
Jan 3, 2006
16
Hello

I'm trying to seperate the rules in my logon script from the logon script, and put them in a xml file. I've created the xml+dtd, but I've been having a very hard time trying to get the vbscript code to work.

Here's what I basicly want to do, in sudo code:
Code:
For Each group in groups
        If UserInGroup(group.groupname) Then
                For Each mapnetworkdrive in actions
                        Call Mapnetworkdrive (mapnetworkdrive.drive, mapnetworkdrive.server,
mapnetworkdrive.share)
                Next
                '... and so on with the other actions
        End If
Next

If somebody would be kind enough to help me out with this I would be gratefull.

Best regards, Egil.

The xml+dtd code:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE logonactions[
        <!ELEMENT logonactions (groups?,users?,computers?)>
                <!ELEMENT runprogram        (program,message)>
                <!ELEMENT mapnetworkdrive   (drive,server,share)>
                <!ELEMENT addprinter        (domain,server,printer)>
                <!ELEMENT setdefaultprinter (#PCDATA)>
                <!ELEMENT program           (#PCDATA)>
                <!ELEMENT message           (#PCDATA)>
                <!ELEMENT drive             (#PCDATA)>
                <!ELEMENT server            (#PCDATA)>
                <!ELEMENT share             (#PCDATA)>
                <!ELEMENT domain            (#PCDATA)>
                <!ELEMENT printer           (#PCDATA)>
                <!ELEMENT actions
(mapnetworkdrive*,addprinter*,setdefaultprinter?,runprogram*)>

                <!ELEMENT groups (group*)>
                        <!ELEMENT group (groupname,actions)>
                                <!ELEMENT groupname (#PCDATA)>

                <!ELEMENT users (user*)>
                        <!ELEMENT user (username,actions)>
                                <!ELEMENT username (#PCDATA)>

                <!ELEMENT computers (computer*)>
                        <!ELEMENT computer (computername,actions)>
                                <!ELEMENT computername (#PCDATA)>
]>

<logonactions>
        <groups>
                <group>
                        <groupname>standard</groupname>
                        <actions>
                                <mapnetworkdrive>
                                        <drive>G</drive>
                                        <server>srv999b</server>
                                        <share>NETAPPL</share>
                                </mapnetworkdrive>
                                <mapnetworkdrive>
                                        <drive>R</drive>
                                        <server>srv100p</server>
                                        <share>file_exchange$</share>
                                </mapnetworkdrive>
                                <runprogram>
                                        <program>program.exe</program>
                                        <message>Running program.exe client</message>
                                </runprogram>
                        </actions>
                </group>
        </groups>
</logonactions>
 
You can do it like this.
[tt]
[blue]'Given or determined by preparative script: xfile, susrgroup
xfile="//server/share/xfile.xml"
susrgroup="standard"
[/blue]
set oparser=createobject("msxml2.domdocument")
with oparser
.async=false
.setproperty "SelectionLanguage","XPath"
.validateonparse=false
.load xfile
end with

if oparser.parseerror.errorcode<>0 then
wscript.echo "xml file " & xfile & " is not well-formed or not found." & vbcrlf & "Operation aborted."
clearup
wscript.quit 999
end if

set ousrgroup=nothing
set xmldoc=oparser.documentelement
set ogrouplist=xmldoc.selectNodes("//groupname")
for each ogroup in ogrouplist
if lcase(ogroup.text)=susrgroup then
set ousrgroup=ogroup
wscript.echo "group identified, do something here" & vbcrlf & "user's group : " & ogroup.text
end if
next

if ousrgroup is nothing then
wscript.echo "User's group is not found. Operation aborted."
clearup
wscript.quit 998
end if

set oactionlist=ousrgroup.selectNodes("../actions/*")
if oactionlist is nothing then
wscript.echo "No action to take. Operation aborted."
clearup
wscript.quit 997
end if
wscript.echo "number of action items : " & oactionlist.length

dim aaction_param()
for each oaction in oactionlist 'eg mapnetworkdrive [1]
saction=oaction.tagName
redim aaction_param(-1)
redim aaction_param(oaction.childNodes.length-1)
i=0
for each oaction_spec in oaction.childNodes
aaction_param(i)=oaction_spec.text
i=i+1
next
wscript.echo "Action name: " & saction & vbcrlf & "action param: " & join(aaction_param,",")
select case lcase(saction)
[blue]'I pass an array containing all the necessary parameters, make the necessary adjustments[/blue]
case "mapnetworkdrive"
[blue]'call Mapnetworkdrive(aaction_param[/blue]
case "runprogram"
[blue]'call Runprogram(aaction_param)[/blue]
case else
[blue]'call Whattodo(aaction_param)[/blue]
end select
next
clearup
wscript.quit 0

sub clearup
set oactionlist=nothing
set ousrgroup=nothing
set ogrouplist=nothing
set xmldoc=nothing
set oparser=nothing
end sub
[/tt]
All echos are for illustration purpose, feel free to comment them out.
 
doh, didn't see your reply before I managed to get it working my self. Thank you anyway.

Here's how my solution ended up looking (can probably be tweaked a lot):

Code:
Dim strWorkstation, strUser
strWorkstation = "pc100100"
strUser = "egh.dk"

' XML Parse test
Private Sub ParseXMLFile(strXMLFile)
	Dim oXMLDoc, bSuccess
	Set oXMLDoc = CreateObject("Microsoft.XMLDOM")
	
	oXMLDoc.async = "false"
	' Try loading the xmlfile
	bSuccess = oXMLDoc.load(strXMLFile)

	If bSuccess Then
		Dim sXPath, colNodes, iIndex, oNode, sNodeName
		Dim colActions, aIndex, aNode, colParams, strDrive
		Dim strServer, strShare, strPrinter, strProgram, strMessage

		' Make a collection of the groups
		sXPath = "//LogonRules/Groups/Group"
		Set colNodes = oXMLDoc.selectNodes(sXPath)
		
		' Loop through collection of groups
		For iIndex = 0 To colNodes.length - 1
			Set oNode = colNodes(iIndex)
			' Get the name of the group
			sNodeName = oNode.getAttribute("name")
			' Test if user is in group and execute the actions if so
			If InGroup(sNodeName) Then
				' Get the actions belonging to current node
				sXPath = "//LogonRules/Groups/Group[@name='" & sNodeName & "']/Action"
				Set colActions = oXMLDoc.selectNodes(sXPath)
				' Execute the actions
				ExecuteActions(colActions)
			End If
		Next

		' Make a collection of the computers
		sXPath = "//LogonRules/Computers/Computer"
		Set colNodes = oXMLDoc.selectNodes(sXPath)
		
		' Loop through collection of computers
		For iIndex = 0 To colNodes.length - 1
			Set oNode = colNodes(iIndex)
			' Get the name of the computer
			sNodeName = oNode.getAttribute("name")
			' Test if user is in group and execute the actions if so
			If sNodeName = strWorkstation Then
				' Get the actions belonging to current node
				sXPath = "//LogonRules/Computers/Computer[@name='" & sNodeName & "']/Action"
				Set colActions = oXMLDoc.selectNodes(sXPath)
				' Execute the actions
				ExecuteActions(colActions)
			End If
		Next

		' Make a collection of the users
		sXPath = "//LogonRules/Users/User"
		Set colNodes = oXMLDoc.selectNodes(sXPath)
		
		' Loop through collection of users
		For iIndex = 0 To colNodes.length - 1
			Set oNode = colNodes(iIndex)
			' Get the name of the computer
			sNodeName = oNode.getAttribute("name")
			' Test if user is in group and execute the actions if so
			If sNodeName = strUser Then
				' Get the actions belonging to current node
				sXPath = "//LogonRules/Users/User[@name='" & sNodeName & "']/Action"
				Set colActions = oXMLDoc.selectNodes(sXPath)
				' Execute the actions
				ExecuteActions(colActions)
			End If
		Next
	Else
		' The document failed to load.
		Dim strErrText
		' Obtain the ParseError object
		Set xPE = oXMLDoc.parseError
		With xPE
			strErrText = "Your XML Document failed to load " & _
				"due the following error." & vbCrLf & _
				"Error #: " & .errorCode & ": " & xPE.reason & _
				"Line #: " & .Line & vbCrLf & _
				"Line Position: " & .linepos & vbCrLf & _
				"Position In File: " & .filepos & vbCrLf & _
				"Source Text: " & .srcText & vbCrLf & _
				"Document URL: " & .url
		End With
		MsgBox strErrText, vbExclamation
		
		' Clean up used memory
		Set xPE = Nothing
	End If

	' Clean up
	Set oXMLDoc = Nothing
End Sub

Private Sub ExecuteActions(colActions)
	' Loop through collections of actions
	For aIndex = 0 To colActions.length - 1
		Set aNode = colActions(aIndex)
		Select Case aNode.getAttribute("type")
			Case "mapdrive"
				' Getting all childnodes for the current action
				Set colParams = aNode.childNodes
				For Each param In colParams
					Select Case param.nodeName
						Case "Drive" strDrive = param.text		
						Case "Server" strServer = param.text
						Case "Share" strShare = param.text
					End Select
				Next
				' Map the network drive
				Call MapDrive(strDrive,strServer,strShare)
			Case "addprinter"
				' Getting all childnodes for the current action
				Set colParams = aNode.childNodes
				For Each param In colParams
					Select Case param.nodeName
						Case "Server" strServer = param.text
						Case "Printer" strPrinter = param.text
					End Select
				Next
				' Add the printer
				Call AddPrinter(strServer,strPrinter)
			Case "setprinter"
				' Getting all childnodes for the current action
				Set colParams = aNode.childNodes
				For Each param In colParams
					Select Case param.nodeName
						Case "Printer" strPrinter = param.text
					End Select
				Next
				' Add the printer
				Call SetDefaultPrinter(strPrinter)
			Case "execute"
				' Getting all childnodes for the current action
				Set colParams = aNode.childNodes
				For Each param In colParams
					Select Case param.nodeName
						Case "Program" strProgram = param.text
						Case "Message" strMessage = param.text
					End Select
				Next
				' Add the printer
				Call RunProgramInBackground(strProgram,strMessage)
		End Select
	Next
End Sub

Function InGroup(strGroup)
	Wscript.Echo "Fun InGroup: " & strGroup
	InGroup = true
End Function

Private Sub MapDrive(strDrive,strServer,strShare)
	Wscript.Echo "map " & strDrive & " to " & strServer & "\" & strShare
End Sub

Private Sub AddPrinter(strServer,strPrinter)
	Wscript.Echo "Add " & strServer & "\" & strPrinter
End Sub

Private Sub SetDefaultPrinter(strPrinter)
	Wscript.Echo "Default printer: " & strPrinter
End Sub

Private Sub RunProgramInBackground(strProgram,strMessage)
	Wscript.Echo "Run progarm: " & strMessage & " - " & strProgram
End Sub

Call ParseXMLFile("xmlfile.xml")

... and the xml+dtd file:
Code:
<?xml version="1.0" encoding="utf-8" ?> 
<!DOCTYPE LogonRules [
	<!ELEMENT LogonRules (Groups?,Computers?,Users?)>
	<!ELEMENT Groups (Group*)>
	<!ELEMENT Group (Action*)>
	<!ATTLIST Group name CDATA #REQUIRED>
	<!ELEMENT Computers (Computer*)>
	<!ELEMENT Computer (Action*)>
	<!ATTLIST Computer name CDATA #REQUIRED>
	<!ELEMENT Users (User*)>
	<!ELEMENT User (Action*)>
	<!ATTLIST User name CDATA #REQUIRED>
	<!ELEMENT Action (((Drive?,Server?)|(Program?,Message?)),(Share|Printer)?)>
	<!ATTLIST Action type (mapdrive|addprinter|setprinter|execute) #REQUIRED>
	<!ELEMENT Drive (#PCDATA)>
	<!ELEMENT Server (#PCDATA)>
	<!ELEMENT Share (#PCDATA)>
	<!ELEMENT Printer (#PCDATA)>
	<!ELEMENT Program (#PCDATA)>
	<!ELEMENT Message (#PCDATA)>
]>
<LogonRules>
	<Groups>
		<Group name="test">
			<Action type="mapdrive">
				<Drive>G:</Drive>
				<Server>srv999b</Server>
				<Share>NETAPPL</Share>
			</Action>
			<Action type="mapdrive">
				<Drive>R:</Drive>
				<Server>srv100p</Server>
				<Share>file_exchange$</Share>
			</Action>
			<Action type="addprinter">
				<Server>srv100f</Server>
				<Printer>sl01</Printer>
			</Action>
			<Action type="execute">
				<Program>\\SRV999b\NETAPPL\mcafee70\EPOClient\AgentUp.exe</Program> 
				<Message>Running AgentUp client</Message> 
			</Action>
			<Action type="setprinter">
				<Printer>sl01</Printer>
			</Action>
		</Group>
		<Group name="net100dk">
			<Action type="mapdrive">
				<Drive>G:</Drive>
				<Server>srv999b</Server>
				<Share>NETAPPL</Share>
			</Action>
			<Action type="mapdrive">
				<Drive>R:</Drive>
				<Server>srv100p</Server>
				<Share>file_exchange$</Share>
			</Action>
			<Action type="addprinter">
				<Server>srv100f</Server>
				<Printer>sl01</Printer>
			</Action>
			<Action type="execute">
				<Program>\\SRV999b\NETAPPL\mcafee70\EPOClient\AgentUp.exe</Program> 
				<Message>Running AgentUp client</Message> 
			</Action>
			<Action type="setprinter">
				<Printer>sl01</Printer>
			</Action>
		</Group>
	</Groups>
	<Computers>
		<Computer name="pc100100">
			<Action type="mapdrive">
				<Drive>R:</Drive>
				<Server>srv100p</Server>
				<Share>file_exchange$</Share>
			</Action>
			<Action type="addprinter">
				<Server>srv100f</Server>
				<Printer>sl01</Printer>
			</Action>
			<Action type="execute">
				<Program>\\SRV999b\NETAPPL\mcafee70\EPOClient\AgentUp.exe</Program> 
				<Message>Running AgentUp client</Message> 
			</Action>
			<Action type="setprinter">
				<Printer>sl01</Printer>
			</Action>
		</Computer>
		<Computer name="pc100101">
			<Action type="mapdrive">
				<Drive>R:</Drive>
				<Server>srv100p</Server>
				<Share>file_exchange$</Share>
			</Action>
			<Action type="addprinter">
				<Server>srv100f</Server>
				<Printer>sl01</Printer>
			</Action>
			<Action type="execute">
				<Program>\\SRV999b\NETAPPL\mcafee70\EPOClient\AgentUp.exe</Program> 
				<Message>Running AgentUp client</Message> 
			</Action>
			<Action type="setprinter">
				<Printer>sl01</Printer>
			</Action>
		</Computer>
	</Computers>
	<Users>
		<User name="egh.dk">
			<Action type="execute">
				<Program>\\SRV999b\NETAPPL\mcafee70\EPOClient\AgentUp.exe</Program> 
				<Message>Running AgentUp client</Message> 
			</Action>
		</User>
	</Users>
</LogonRules>
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top