myXMLTools.rbbas 12.8 KB
Newer Older
Rusty Myers's avatar
Rusty Myers committed
1
#tag Module
Protected Module myXMLTools
	#tag Method, Flags = &h21
		Private Function getXMLkeyString(paramXMLkey as string) As string
		  dim mXMLkeyStr as string
		  
		  //LogToFile(CurrentMethodName + ": ---->")
		  //LogToFile(CurrentMethodName + ": paramXMLkey received = '" + paramXMLkey + "'")
		  
		  mXMLkeyStr = NthField(paramXMLkey,">",1)
		  mXMLkeyStr = ReplaceAll(mXMLkeyStr,"<","") // Remove the < and >'s if found
		  mXMLkeyStr = ReplaceAll(mXMLkeyStr,">","")
		  
		  //LogToFile(CurrentMethodName + ": Returning string = '" + mXMLkeyStr + "'")
		  //LogToFile(CurrentMethodName + ": <----")
		  
		  return mXMLkeyStr
		  
		End Function
	#tag EndMethod

	#tag Method, Flags = &h1
		Protected Function getXMLPlistData(paramXMLdataString as string, paramXMLtreeArrayToFollow() as string, byRef paramDataArrayToFill() as string) As Boolean
		  // This method assumes that we're dealing with plist files.
		  
		  // paramXMLtreeArrayToFollow = {"<plist>","<dict>","<key>VolumesFromDisks</key>","<array>")
		  
		  // Sample data: paramXMLdataString =
		  
		  // <?xml version="1.0" encoding="UTF-8"?>
		  // <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
		  // <plist version="1.0">
		  // <dict>
		  // <key>AllDisks</key>
		  // <array>
		  // <string>disk0</string>
		  // <string>disk0s1</string>
		  // <string>disk0s2</string>
		  // <string>disk1</string>
		  // <string>disk1s1</string>
		  // <string>disk1s2</string>
		  // </array>
		  // <key>VolumesFromDisks</key>
		  // <array>
		  // <string>Boot</string>
		  // <string>keys</string>
		  // </array>
		  // <key>WholeDisks</key>
		  // <array>
		  // <string>disk0</string>
		  // <string>disk1</string>
		  // </array>
		  // </dict>
		  // </plist>
		  
		  // Result (paramDataArrayToFill) should be: {"<string>Boot</string>","<string>keys</string>"}
		  
		  dim mXMLdoc as XmlDocument
		  dim mXMLroot, mPrefNode, mChildNode as XMLNode
		  dim mXMLtreeToFollowIndex as integer
		  dim mPrefNodeLocalName as string
		  dim mXMLtreeSearchElement as string
		  dim mXMLtreeSearchElementValue as string
		  dim mXMLkeyName as string
		  dim mFoundXMLdata as Boolean
		  dim mTempStr as string
		  
		  // LogToFile(CurrentMethodName + ": ---->")
		  
		  if (paramXMLdataString = "") then
		    LogToFile(CurrentMethodName + ": ERROR: paramXMLdataString received is empty. Returning FALSE.")
		    LogToFile(CurrentMethodName + ": <----")
		    return false
		  else
		    // LogToFile(CurrentMethodName + ": paramXMLdataString =" + EndOfLine + paramXMLdataString + EndOfLine)
		  end if
		  
		  if ( (paramXMLtreeArrayToFollow = nil) or (UBound(paramXMLtreeArrayToFollow)<=0) ) then
		    LogToFile(CurrentMethodName + ": ERROR: paramXMLtreeArrayToFollow received is nil or contains no elements. Returning FALSE.")
		    LogToFile(CurrentMethodName + ": <----")
		    return false
		  else
		    // LogToFile(CurrentMethodName + ": paramXMLtreeArrayToFollow = {" + join(paramXMLtreeArrayToFollow,",") + "}" )
		  end if
		  
		  if (paramDataArrayToFill = nil) then
		    LogToFile(CurrentMethodName + ": ERROR: paramDataArrayToFill received is nil. Returning FALSE.")
		    LogToFile(CurrentMethodName + ": <----")
		    return false
		  end if
		  
		  redim paramDataArrayToFill(-1) // Erase all data, we're going to refill it next...
		  mFoundXMLdata = false
		  
		  mXMLdoc = new XmlDocument
		  
		  #pragma BreakOnExceptions off // Don't BreakOnExceptions in the IDE on this, just log it and return FALSE
		  try
		    mXMLdoc.LoadXml paramXMLdataString
		  catch
		    LogToFile(CurrentMethodName + ": ERROR: Failed to .loadXML received XML string data (paramXMLdataString). Is it correctly formed XML?")
		    LogToFile(CurrentMethodName + ": <----")
		    return false
		  end
		  #pragma BreakOnExceptions on
		  
		  mXMLroot = mXMLdoc
		  
		  mPrefNode = mXMLroot.FirstChild
		  
		  mXMLtreeToFollowIndex = 0
		  mXMLkeyName = ""
		  
		  while (mPrefNode <> nil)
		    
		    mPrefNodeLocalName = mPrefNode.LocalName
		    //LogToFile(CurrentMethodName + ": XML Data: mPrefNodeLocalName = '" + mPrefNodeLocalName + "'")
		    
		    if (mPrefNode.FirstChild = nil) then // ie, '<dict>' versus '<dict>AllDisks</dict>'
		      
		      //LogToFile(CurrentMethodName + ": XML Data: mXMLkeyName is NIL. Setting to an empty string.")
		      
		    else // '<dict>AllDisks</dict>'
		      
		      mXMLkeyName = mPrefNode.FirstChild.Value
		      //LogToFile(CurrentMethodName + ": XML Data: mXMLkeyName = '" + mXMLkeyName + "'")
		      
		    end if
		    
		    mXMLtreeSearchElement = getXMLkeyString(paramXMLtreeArrayToFollow(mXMLtreeToFollowIndex))
		    //LogToFile(CurrentMethodName + ": mXMLtreeSearchElement = '" + mXMLtreeSearchElement + "'")
		    
		    mXMLtreeSearchElementValue = paramXMLtreeArrayToFollow(mXMLtreeToFollowIndex)
		    mXMLtreeSearchElementValue = ReplaceAll(mXMLtreeSearchElementValue,("<" + mXMLtreeSearchElement + ">"),"")
		    mXMLtreeSearchElementValue = ReplaceAll(mXMLtreeSearchElementValue,("</" + mXMLtreeSearchElement + ">"),"")
		    //LogToFile(CurrentMethodName + ": mXMLtreeSearchElementValue = '" + mXMLtreeSearchElementValue + "'")
		    
		    if (mXMLtreeSearchElement = "plist") then
		      if ( InStr(mPrefNodeLocalName,mXMLtreeSearchElement)>0 ) then //catches all versions of the plist format, ie: "<plist version="1.0">" could be "<plist version="1.1">, etc.
		        //LogToFile(CurrentMethodName + ": XML Data: Found plist node, going to first child node next...")
		        mPrefNode = mPrefNode.FirstChild
		        mXMLtreeToFollowIndex = mXMLtreeToFollowIndex + 1
		        Continue // Skip the rest of the code below, go to the next while loop interation
		      end if
		    end if
		    
		    // Check if the found XML tree item is a match and if so, go in one level:
		    
		    select case mPrefNodeLocalName
		      
		    case mXMLtreeSearchElement
		      
		      //LogToFile(CurrentMethodName + ": XML Data: Found matching XML tree node to search element (<" + mXMLtreeSearchElement + ">)") // Found the matching XML key node.
		      
		      if (mXMLtreeToFollowIndex = (ubound(paramXMLtreeArrayToFollow)-1) ) then // We're on the last key element in the paramXMLdataString, but need to check that it's the right key next...
		        
		        //LogToFile(CurrentMethodName + ": XML Data: Checking key value mXMLtreeSearchElementValue next ...")
		        
		        if ( (mXMLkeyName<>"") and (mXMLtreeSearchElementValue<>"") and (mXMLkeyName = mXMLtreeSearchElementValue) ) then
		          // LogToFile(CurrentMethodName + ": XML Data: Found a matching key! (<" + mXMLkeyName + ">) Next obtaining the child data elements...")
		          
		          mPrefNode = mPrefNode.NextSibling
		          mXMLtreeToFollowIndex = mXMLtreeToFollowIndex + 1
		          mXMLtreeSearchElement = getXMLkeyString(paramXMLtreeArrayToFollow(mXMLtreeToFollowIndex))
		          
		          // mXMLtreeSearchElement = "junkTest" // Debugging only
		          
		          if (mXMLtreeSearchElement = "boolean") then
		            mTempStr = mPrefNode.LocalName
		            //LogToFile(CurrentMethodName + ": Boolean value found. Value = '" + mTempStr + "'")
		            paramDataArrayToFill.Append mTempStr
		            mFoundXMLdata = true
		            exit
		          end if
		          
		          if (mPrefNode.LocalName = mXMLtreeSearchElement) then // We have what we need!
		            
		            //LogToFile(CurrentMethodName + ": XML Data: SUCCESS! Found last XML data item. (<" + mXMLtreeSearchElement + _
		            //">) Adding data elements to the input array next ...")
		            
		            if ( mPrefNode.FirstChild = nil) then // Try the next sibling instead
		              
		              // LogToFile(CurrentMethodName + ": mPrefNode.FirstChild is nil, so trying mPrefNode.NextSibling next ... could be an empty string key value?")
		              
		              mPrefNode = mPrefNode.NextSibling
		              
		              if ( mPrefNode <> nil ) then
		                mTempStr = mPrefNode.Value
		                // LogToFile(CurrentMethodName + ": mPrefNode is NOT nil, data to append = '" + mTempStr + "'")
		                paramDataArrayToFill.Append mTempStr
		              else
		                // LogToFile(CurrentMethodName + ": ERROR: mPrefNode IS nil, nothing found!")
		              end if
		              
		            else
		              
		              mPrefNode = mPrefNode.FirstChild
		              
		              while (mPrefNode <> nil)
		                if (mPrefNode.ToString = "") then
		                  mTempStr = mPrefNode.Value // ie, "disk0" (no tags.)
		                else
		                  mTempStr = removeXMLtags(mPrefNode.ToString) // ie, "<string>disk0</string>" (with tags!)
		                end if
		                paramDataArrayToFill.Append mTempStr
		                //LogToFile(CurrentMethodName + ": XML Data: Added XML data element '" + mTempStr + "' to the paramDataArrayToFill array.")
		                mPrefNode = mPrefNode.NextSibling
		              wend
		              
		            end if
		            
		            mFoundXMLdata = true
		            exit // exit the loop, we're done
		            
		          else
		            
		            LogToFile(CurrentMethodName + ": ERROR: Unable to locate last XML element data item! (" + mXMLtreeSearchElement + ")")
		            exit // exit the loop, we're done
		            
		          end if
		          
		          exit // exit the loop, we're done
		          
		        else // the next sibling might not have a key name
		          
		          if (mPrefNode.NextSibling <> nil) then
		            //LogToFile(CurrentMethodName + ": mPrefNode.NextSibling exists, moving to it next...")
		            mPrefNode = mPrefNode.NextSibling
		          else
		            //LogToFile(CurrentMethodName + ": ERROR: mPrefNode.NextSibling is NIL! Can't go any further to search for data, exiting search loop.")
		            exit // exit the loop, we're done
		          end if
		          
		        end if
		        
		      else // ELSE, continue on to the next child node...
		        
		        mPrefNode = mPrefNode.FirstChild
		        mXMLtreeToFollowIndex = mXMLtreeToFollowIndex + 1
		        
		      end if
		      
		    else
		      
		      //LogToFile(CurrentMethodName + ": XML Data: Current XML node local name (<" + mPrefNodeLocalName + ">) does NOT match search element (<" + mXMLtreeSearchElement + ">). Checking next XML sibling...")
		      mPrefNode = mPrefNode.NextSibling
		      
		    end select
		    
		  wend
		  
		  // LogToFile(CurrentMethodName + ": <----")
		  
		  return mFoundXMLdata
		End Function
	#tag EndMethod

	#tag Method, Flags = &h21
		Private Function removeXMLtags(paramXMLelement as string) As string
		  dim mKeyName as string
		  dim mReturnString as string
		  
		  LogToFile(CurrentMethodName + ": ---->")
		  LogToFile(CurrentMethodName + ": Received XML string = '" + paramXMLelement + "'")
		  
		  if (paramXMLelement = "") then
		    LogToFile(CurrentMethodName + ": The received string is empty, nothing to do, returning ''.")
		    LogToFile(CurrentMethodName + ": <----")
		    return ""
		  end if
		  
		  // Determine what the key title is first...
		  
		  mKeyName = NthField(paramXMLelement,">",1) // ie, "<string"
		  mKeyName = NthField(mKeyName,"<",2) // ie, "string"
		  
		  mReturnString = paramXMLelement // ie, <string>disk0s2</string>
		  mReturnString = ReplaceAll( mReturnString,("<" + mKeyName + ">","") ) // ie, disk0s2</string>
		  mReturnString = ReplaceAll( mReturnString,("</" + mKeyName + ">","") ) // ie, disk0s2
		  
		  LogToFile(CurrentMethodName + ": Returning string = '" + mReturnString + "'")
		  LogToFile(CurrentMethodName + ": <----")
		  
		  return mReturnString
		End Function
	#tag EndMethod


	#tag Constant, Name = kIndentXML, Type = String, Dynamic = False, Default = \"<\?xml version\x3D\"1.0\" encoding\x3D\"UTF-8\"\?><xsl:transform version\x3D\"1.0\" xmlns:xsl\x3D\"http://www.w3.org/1999/XSL/Transform\"><xsl:output method\x3D\"xml\" indent\x3D\"yes\" /><xsl:template match\x3D\"/\"><xsl:copy-of select\x3D\"/\" /></xsl:template></xsl:transform>", Scope = Protected
	#tag EndConstant


	#tag ViewBehavior
		#tag ViewProperty
			Name="Index"
			Visible=true
			Group="ID"
			InitialValue="-2147483648"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Left"
			Visible=true
			Group="Position"
			InitialValue="0"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Name"
			Visible=true
			Group="ID"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Super"
			Visible=true
			Group="ID"
			InheritedFrom="Object"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Top"
			Visible=true
			Group="Position"
			InitialValue="0"
			InheritedFrom="Object"
		#tag EndViewProperty
	#tag EndViewBehavior
End Module
#tag EndModule