I know there are a lot questions similar to this one but i couldn't find the right answer for me. I need to replace all phrases in xml file that starts and ends with % (e.g. %TEST% or %TEST-NEW% )
So far i have these tryouts:
This was my test one that works in the console but has only 1 line of string
zone = "<test>%TEST%</test>"
MsgBox zone
'Setting the regex and cheking the matches
set regex = New RegExp
regex.IgnoreCase = True
regex.Global = True
regex.Pattern = "%.+%"
Set myMatches = regex.execute(zone)
For each myMatch in myMatches
Wscript.echo myMatch
result = Replace(zone,myMatch,"")
next
MsgBox result
but when i try to do the same from a file with this...
Dim objStream, strData, fields
Set objStream = CreateObject("ADODB.Stream")
objStream.CharSet = "utf-8"
objStream.Open
objStream.LoadFromFile("C:\test\test.xml")
strData = objStream.ReadText()
Wscript.echo strData
set regex = New RegExp
regex.IgnoreCase = True
regex.Global = True
regex.Pattern = "%.+%"
Set myMatches = regex.execute(strData)
For each myMatch in myMatches
Wscript.echo myMatch
result = Replace(strData,myMatch,"")
next
Wscript.echo result
...the first echo returns correctly the contains of the file and then the second echo in the loop echoes all the matches that i need to replace , but the last echo return the same result as the first (nothing is being replaced)
The xml looks like this (just for example):
<script>%TEST%</script>
<value>%VALUE%</value>
<test>%TEST%</test>
P.S. I need to loop through xml files in a specific folder and replace the phrase from above. Can anyone help?
The final script that works for me(big thanks to Tomalak):
Option Explicit
Dim path, doc, node, placeholder,srcFolder,FSO,FLD,fil
Set placeholder = New RegExp
placeholder.Pattern = "%[^%]+%"
placeholder.Global = True
srcFolder = "C:\test"
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FLD = FSO.GetFolder(srcFolder)
For each fil In FLD.Files
if LCase(FSO.GetExtensionName(fil.Name)) = "xml" Then
path = "C:\test\" & fil.Name
' 1. parse the XML into a DOM
Set doc = LoadXmlDoc(path)
' 2. select and modify DOM nodes
For Each node In doc.selectNodes("//text()|//#*")
node.nodeValue = SubstitutePlaceholders(node.nodeValue)
Next
' 3. save modified DOM back to file
doc.save path
End If
Next
' --------------------------------------------------------------------------
Function LoadXmlDoc(path)
Set LoadXmlDoc = CreateObject("MSXML2.DomDocument.6.0")
LoadXmlDoc.async = False
LoadXmlDoc.load path
If LoadXmlDoc.parseError.errorCode <> 0 Then
WScript.Echo "Error in XML file."
WScript.Echo LoadXmlDoc.parseError.reason
WScript.Quit 1
End If
End Function
' --------------------------------------------------------------------------
Function SubstitutePlaceholders(text)
Dim match
For Each match In placeholder.Execute(text)
text = Replace(text, match, GetReplacement(match))
Next
SubstitutePlaceholders = text
End Function
' --------------------------------------------------------------------------
Function GetReplacement(placeholder)
Select Case placeholder
Case "%TEST%": GetReplacement = "new value"
Case "%BLA%": GetReplacement = "other new value"
Case Else: GetReplacement = placeholder
End Select
End Function
' --------------------------------------------------------------------------
Never use regular expressions on XML files, period.
Use an XML parser. It will be simpler, the code will be easier to read, and most importantly: It will not break the XML.
Here is how to modify your XML document in the proper way.
Option Explicit
Dim path, doc, node, placeholder
Set placeholder = New RegExp
placeholder.Pattern = "%[^%]+%"
placeholder.Global = True
path = "C:\path\to\your.xml"
' 1. parse the XML into a DOM
Set doc = LoadXmlDoc(path)
' 2. select and modify DOM nodes
For Each node In doc.selectNodes("//text()|//#*")
node.nodeValue = SubstitutePlaceholders(node.nodeValue)
Next
' 3. save modified DOM back to file
doc.save path
' --------------------------------------------------------------------------
Function LoadXmlDoc(path)
Set LoadXmlDoc = CreateObject("MSXML2.DomDocument.6.0")
LoadXmlDoc.async = False
LoadXmlDoc.load path
If LoadXmlDoc.parseError.errorCode <> 0 Then
WScript.Echo "Error in XML file."
WScript.Echo LoadXmlDoc.parseError.reason
WScript.Quit 1
End If
End Function
' --------------------------------------------------------------------------
Function SubstitutePlaceholders(text)
Dim match
For Each match In placeholder.Execute(text)
text = Replace(text, match, GetReplacement(match))
Next
SubstitutePlaceholders = text
End Function
' --------------------------------------------------------------------------
Function GetReplacement(placeholder)
Select Case placeholder
Case "%TEST%": GetReplacement = "new value"
Case "%BLA%": GetReplacement = "other new value"
Case Else: GetReplacement = placeholder
End Select
End Function
' --------------------------------------------------------------------------
The XPath expression //text()|//#* targets all text nodes and all attribute nodes. Use a different XPath expression if necessary. (I will not cover XPath basics here, there are plenty of resources for learning it.)
Of course this solution uses regular expressions, but it does that on the text values that the XML structure contains, not on the XML structure itself. That's a crucial difference.
Related
Source="C:\\SourceDirectory"
Destination="C:\\DestinationDirectory"
pattern1="^"&"TestApp"&".*"&"zip"
Function RegExTest(pattern, stringToSearch)
Dim regEx ' Create variable.
Set regEx = New RegExp ' Create a regular expression.
regEx.Pattern = pattern ' Set pattern.
regEx.IgnoreCase = True ' Set case insensitivity.
regEx.Global = True ' Set global applicability.
Set Matches = regEx.Execute(stringToSearch) ' Execute search.q
IF Matches.count > 0 Then
RegExTest = True
End IF
End Function
Sub ProcessFile(Source, Destination)
Set Folder = FSO.GetFolder(Destination)
If Not (Right(Destination, 1) = "\") Then
Destination = Destination & "\"
End If
' Deal with Duplicate Files
Dim sourceArr, File
sourceArr = Split(Source, "\")
File = sourceArr(UBound(sourceArr))
If Not FSO.FileExists(Destination & File) Then
returnValue = True
For Each File In Folder.Files
if RegExTest(pattern1,File.Name) And returnValue = "True" Then
WScript.Echo("filename: "&File.Name&" filesize: "&File.Size)
End If
Next
FSO.MoveFile Source, Destination
End If
End Sub
I have only 3 TestApp.zip files but I'm getting 9 files which is resulting false file size in total, Folder structure is like this
Any help much appreciated!! Thanks in advance
I am trying to write a function which will delete all sheets except the one passed as parameter. Below function is being called but function does not delete any sheets. How can I delete all worksheets except one?
........
Set ExcelObj = createobject("excel.application")
ExcelObj.Visible = true
Set ConfigFile = ExcelObj.Workbooks.Open (FilePath)
Set ConfigSheet = ConfigFile.Worksheets("Scripts")
Set ConfigApplicationSheet = ConfigFile.Worksheets("Applications")
Set ExecutiveSummarySheet = ConfigFile.Worksheets("Summary")
ExcelObj.ActiveWorkBook.SaveAs SummaryFilePath
DeleteSheet "ConfigScripSheet","Summary"
Function DeleteSheet(ConfigSheet,mySheetname)
'Writing Name and Path of each File to Output File
For Each ObjFile In ObjFiles
ObjOutFile.WriteLine(ObjFile.Name & String(50 - Len(ObjFile.Name), " ") & ObjFile.Path)
Next
ObjOutFile.Close
DeleteSheet = 0
ExcelObj.DisplayAlerts = False
For Each objWorksheet In ConfigSheet.Worksheets
If not objWorksheet.Name = mySheetname Then
DeleteSheet = 1
ConfigScripSheet.sheets(objWorksheet.Name).Select
ConfigScripSheet.sheets(objWorksheet.Name).Delete
ExcelObj.DisplayAlerts = False
End If
Next
End Function
Trying to correct your code above was too much of a minefield for me as I couldn't tell what you meant in several places - so I rewrote it based on what you had said in the description was your goal.
The code below will open the file, associate the objects the way you had them, pass the workbook object and a sheet name not to be deleted into the DeleteSheet function, which will delete any sheet in the workbook that is not named as per the passed in parameter SheetNameNotToDelete
Let me know if any of the code is unclear.
Option Explicit ' Forces declaration of variables
Dim FilePath, SummaryFilePath '<-- Need set to some value!
FilePath = ""
SummaryFilePath = ""
Dim ExcelObj : Set ExcelObj = CreateObject("Excel.Application")
Dim ConfigFile : Set ConfigFile = ExcelObj.Workbooks.Open(FilePath)
Dim ConfigSheet : Set ConfigSheet = ConfigFile.Worksheets("Scripts")
Dim ConfigApplicationSheet : Set ConfigApplicationSheet = ConfigFile.Worksheets("Applications")
Dim ExecutiveSummarySheet : Set ExecutiveSummarySheet = ConfigFile.Worksheets("Summary")
ExcelObj.ThisWorkbook.SaveAs SummaryFilePath
DeleteSheet ConfigFile, "Summary"
Function DeleteSheet(ByRef WorkbookObj, ByVal SheetNameNotToDelete)
Dim oWorksheet
For Each oWorksheet In WorkbookObj.Worksheets
If oWorksheet.Name <> SheetNameNotToDelete And WorkbookObj.Worksheets.Count >=2 Then
oWorksheet.Delete ' Excel won't let you delete all worksheets from a workbook
End If ' the check on Count >=2 covers the case where no worksheet exists
Next ' called "Summary" to be left
End Function
I am trying to use Regex to return matching word in vbscript. My hta file is here at gist
My vbs Sub is :-
Sub ProcessFile(FileName)
On Error Resume Next
Set fso = CreateObject("Scripting.FileSystemObject")
Set fileObj = fso.GetFile(FileName)
Set contents = fileObj.OpenAsTextStream(1, 0)
'MsgBox contents.ReadAll
If err.number = 0 then
Set r = New RegExp
r.Global = True
r.Pattern = "\[CATS\]\.(\[[^]]+\])"
Set ms = r.Execute(contents)
For Each m In ms
MsgBox m.SubMatches(0)
demo.innerHTML = demo.innerHTML & m.SubMatches(0)
Next
Else
MsgBox err.number
End If
End Sub
It doesn't return matching words
There is something miss
For a text file containing following text:-
[CATS].[Hello_World1] Lorem Ipsum [CATS].[Hi_Venus1] Demo Text [CATS].[Yo_Moon1] Lorm Ipsum
[CATS].[Hello_World] Lorem Ipsum [CATS].[Hi_Venus] Demo Text [CATS].[Yo_Moon] Lorm Ipsum
It is expected to return [Hello_World1], [Hi_Venus1], [Yo_Moon1], [Hello_World], [Hi_Venus], [Yo_Moon]
You run your code with an active OERN. That hides errors. E.g: contents is a stream (so contents.ReadAll() 'works'). But r.Execute(contents) can't possibly 'work' because .Execute expects/needs a string.
Update wrt comment:
If you know that MsgBox contents.ReadAll displays the string content of the stream, then Set ms = r.Execute(contents.ReadAll()) shouldn't be too hard.
Remember: Set is used to assign an object (stream, match collection, ...) to a variable; so Set str = contents.ReadAll can't possibly 'work' (and you'd be told about that if you'd disabled/removed the OERN).
You could also process it line by line using Do...Loop statement.
Sub ProcessFile(FileName)
Set fso = CreateObject("Scripting.FileSystemObject")
Set fileObj = fso.GetFile(FileName)
Set contents = fileObj.OpenAsTextStream(1, 0)
If err.number = 0 then
Linenum = 0
Do Until contents.AtEndOfStream
line = contents.readline
Linenum = Linenum + 1
Set r = New RegExp
r.Pattern = "\[CATS\]\.(\[[^]]+\])"
Set ms = r.Execute(line)
For Each m In ms
MsgBox m.SubMatches(0)
demo.innerHTML = demo.innerHTML & m.SubMatches(0)
Next
Loop
Else
err.clear
End If
End Sub
I would like to remove the unwanted text from each string in a file.
the input string looks like this
username^time stamp^don't need this printed on printer name more useless info pages printed:some number
I want to remove everything else but keep the username,time stamp,printer name and some number.Then write each line to a file so the output looks like this
username timestamp printername some number
This is the code I'm working with
Set fs = CreateObject("Scripting.FileSystemObject")
sf = "C:\test.txt"
Set f = fs.OpenTextFile(sf, 1) ''1=for reading
s = f.ReadAll
segments = Split(s,"^",-1)
s= segments(1,)
f.Close
Set f = fs.OpenTextFile(sf, 2) ''2=ForWriting
f.Write s
f.Close
There's always a moment that somebody asks "Why not use a regular expression?". This is that moment.
Try this:
Dim re, s, match, matches
s = "Chuck Norris^12-12-2012^don't need this printed on HAL9000 more useless info pages printed:42 "
Set re = new regexp
re.pattern = "(.*)\^(.*)\^.*printed on (\w+).*pages printed:(\d+).*"
re.Global = True
Set matches = re.Execute(s)
Set match = matches(0)
msgbox "username=" & match.submatches(0)
msgbox "time stamp=" & match.submatches(1)
msgbox "printer=" & match.submatches(2)
msgbox "pages printed=" & match.submatches(3)
Neat huh? And I bet you'll figure out how to implement it in your existing code.
Code:
Const csSep = "^"
'username^time^(other arbitrary junk)^printer name^(other arbitrary junk)^page count
Dim sJunk : sJunk = "kurt^01:02:03^some junk^nec p7^nix^123"
WScript.Echo sJunk
Dim aParts : aParts = Split(sJunk, csSep)
Dim sNetto : sNetto = Join(Array(aParts(0),aParts(1),aParts(3),aParts(5)), csSep)
WScript.Echo sNetto
output:
kurt^01:02:03^some junk^nec p7^nix^123
kurt^01:02:03^nec p7^123
I need to go through a text file and check whether the start of each line begins with "Attribute". How should I do this in VB6?
Use a Regex. You will have to include the VBScript Regular Expressions library in your references.
Dim reg As new Scripting.Regex().
reg.Pattern = "^Attribute"
If reg.Match(line) Then
' Do Something
End If
Dim sInput As String, check as Boolean
check = true
Open "myfile" For INPUT As #txtFile
While Not EOF(txtFile)
Input #txtFile, sInput
If Not Mid(sInput,1,9) = "ATTRIBUTE" Then
check = false
End if
sInput = ""
Wend
Close #txtFile
If check = true at the end, all lines start with "ATTRIBUTE", otherwise they do not.
You could try something like this (code not tested) -
Dim ParseDate, AllLinesStartWithAttribute, fso, fs
AllLinesStartWithAttribute = False
Set fso = CreateObject("Scripting.FileSystemObject")
Set fs = fso.OpenTextFile("c:\yourfile", 1, True)
Do Until fs.AtEndOfStream
If Left(fs.ReadLine, 9) <> "Attribute" Then
AllLinesStartWithAttribute = False
Exit Do
End If
Loop
fs.Close
Set fs = Nothing
Once the code is run if the AllLinesStartWithAttribute value is set to true then all lines in your file begin with 'Attribute'. Please note that this code is case sensitive.
Dim fso As New FileSystemObject
Dim ts As TextStream
Dim str As String
Set ts = fso.OpenTextFile(MyFile)
Do While Not ts.AtEndOfStream
str = ts.ReadLine
If InStr(str, "Attribute") = 1 Then
' do stuff
End If
Loop