I've already described an approach of automating actions in Notepad++ with WSH VB script by the link: Search and replace math operations with the result in Notepad++. That approach allows you to assign a keyboard shortcut to the automated action, and add the necessary commands to the script to process the file being edited.
There is the code which adds a property to each object in array, represented in JSON file:
Option Explicit
Const FileEncoding = 0 ' 0 = ASCII, -1 = Unicode, -2 = System Default
Dim objTokens, strTokenType, bTokenMatched
Dim strJSONString, varJSON, strState, i
' check if a file path was passed to the script in the only argument
If WScript.Arguments.Count <> 1 then
CreateObject("WScript.Shell").PopUp "Drop file onto the script", 3, , 48
WScript.Quit
End If
' read json string from the file
strJSONString = ReadFromFile(WScript.Arguments(0), FileEncoding)
' parse json string
ParseJSON strJSONString, varJSON, strState
' check if root element is an array
If strState <> "Array" Then
CreateObject("WScript.Shell").PopUp "JSON root element is not an array", 3, , 48
WScript.Quit
End If
' you can place your own algorithm in this block
' currently it adds a property to each object in array
For i = 0 To UBound(varJSON)
If IsObject(varJSON(i)) Then ' check if the modified element is an object
varJSON(i).Add "item", i ' add property
End If
Next
' serialize json
strJSONString = SerializeJSON(varJSON)
' write json string to the file
WriteToFile strJSONString, WScript.Arguments(0), FileEncoding
CreateObject("WScript.Shell").PopUp "Completed", 1, , 64
Sub ParseJSON(ByVal strContent, varJSON, strState)
' strContent - source JSON string
' varJSON - created object or array to be returned as result
' strState - Object|Array|Error depending on processing to be returned as state
Dim objRegEx, refTokenize
Set refTokenize = GetRef("Tokenize")
Set objTokens = CreateObject("Scripting.Dictionary")
Set objRegEx = CreateObject("VBScript.RegExp")
With objRegEx
' specification http://www.json.org/
.Global = True
.MultiLine = True
.IgnoreCase = True
.Pattern = """(?:\\""|[^""])*""(?=\s*(?:,|\:|\]|\}))"
REM .Pattern = "1"
strTokenType = "str"
strContent = .Replace(strContent, refTokenize)
.Pattern = "(?:[+-])?(?:\d+\.\d*|\.\d+|\d+)e(?:[+-])?\d+(?=\s*(?:,|\]|\}))"
strTokenType = "num"
strContent = .Replace(strContent, refTokenize)
.Pattern = "(?:[+-])?(?:\d+\.\d*|\.\d+|\d+)(?=\s*(?:,|\]|\}))"
strTokenType = "num"
strContent = .Replace(strContent, refTokenize)
.Pattern = "\b(?:true|false|null)(?=\s*(?:,|\]|\}))"
strTokenType = "cst"
strContent = .Replace(strContent, refTokenize)
.Pattern = "\b[A-Za-z_]\w*(?=\s*\:)" ' unspecified name without quotes
strTokenType = "nam"
strContent = .Replace(strContent, refTokenize)
.Pattern = "\s"
strContent = .Replace(strContent, "")
.MultiLine = False
Do
bTokenMatched = False
.Pattern = "<\d+(?:str|nam)>\:<\d+(?:str|num|obj|arr|cst)>"
strTokenType = "prp"
strContent = .Replace(strContent, refTokenize)
.Pattern = "\{(?:<\d+prp>(?:,<\d+prp>)*)?\}"
strTokenType = "obj"
strContent = .Replace(strContent, refTokenize)
.Pattern = "\[(?:<\d+(?:str|num|obj|arr|cst)>(?:,<\d+(?:str|num|obj|arr|cst)>)*)?\]"
strTokenType = "arr"
strContent = .Replace(strContent, refTokenize)
Loop While bTokenMatched
.Pattern = "^<\d+(?:obj|arr)>$" ' unspecified top level array
If Not (.Test(strContent) And objTokens.Exists(strContent)) Then
varJSON = Null
strState = "Error"
Else
Retrieve objTokens, objRegEx, strContent, varJSON
If IsObject(varJSON) Then
strState = "Object"
Else
strState = "Array"
End If
End If
End With
End Sub
Function Tokenize(strMatch, lngPos, strSource)
' fn_replace(strMatch, strSubMatch1[, strSubMatch2[, strSubMatch3 ... ]], lngPos, strSource)
Tokenize = "<" & objTokens.Count & strTokenType & ">"
objTokens(Tokenize) = strMatch
bTokenMatched = True
End Function
Sub Retrieve(objTokens, objRegEx, strTokenKey, varTransfer)
Dim strContent, strType, objMatches, objMatch, strName, varValue, objArrayElts
strType = Left(Right(strTokenKey, 4), 3)
strContent = objTokens(strTokenKey)
With objRegEx
.Global = True
Select Case strType
Case "obj"
.Pattern = "<\d+\w{3}>"
Set objMatches = .Execute(strContent)
Set varTransfer = CreateObject("Scripting.Dictionary")
For Each objMatch In objMatches
Retrieve objTokens, objRegEx, objMatch.Value, varTransfer
Next
Case "prp"
.Pattern = "<\d+\w{3}>"
Set objMatches = .Execute(strContent)
Retrieve objTokens, objRegEx, objMatches(0).Value, strName
Retrieve objTokens, objRegEx, objMatches(1).Value, varValue
If IsObject(varValue) Then
Set varTransfer(strName) = varValue
Else
varTransfer(strName) = varValue
End If
Case "arr"
.Pattern = "<\d+\w{3}>"
Set objMatches = .Execute(strContent)
Set objArrayElts = CreateObject("Scripting.Dictionary")
For Each objMatch In objMatches
Retrieve objTokens, objRegEx, objMatch.Value, varValue
If IsObject(varValue) Then
Set objArrayElts(objArrayElts.Count) = varValue
Else
objArrayElts(objArrayElts.Count) = varValue
End If
Next
varTransfer = objArrayElts.Items
Case "nam"
varTransfer = strContent
Case "str"
varTransfer = Mid(strContent, 2, Len(strContent) - 2)
varTransfer = Replace(varTransfer, "\""", """")
varTransfer = Replace(varTransfer, "\\", "\")
varTransfer = Replace(varTransfer, "\/", "/")
varTransfer = Replace(varTransfer, "\b", Chr(8))
varTransfer = Replace(varTransfer, "\f", Chr(12))
varTransfer = Replace(varTransfer, "\n", vbLf)
varTransfer = Replace(varTransfer, "\r", vbCr)
varTransfer = Replace(varTransfer, "\t", vbTab)
.Global = False
.Pattern = "\\u[0-9a-fA-F]{4}"
Do While .Test(varTransfer)
varTransfer = .Replace(varTransfer, ChrW(("&H" & Right(.Execute(varTransfer)(0).Value, 4)) * 1))
Loop
Case "num"
varTransfer = Eval(strContent)
Case "cst"
Select Case LCase(strContent)
Case "true"
varTransfer = True
Case "false"
varTransfer = False
Case "null"
varTransfer = Null
End Select
End Select
End With
End Sub
Function SerializeJSON(varJSON)
Dim lngIndent
SerializeJSON = ""
lngIndent = 0
Traverse SerializeJSON, lngIndent, varJSON, vbTab, 1
End Function
Sub Traverse(strResult, lngIndent, varElement, strIndent, lngStep)
Dim strVarType, arrKeys, lngIndex, strTemp
strVarType = VarType(varElement)
Select Case True
Case strVarType = vbObject
If varElement.Count = 0 Then
strResult = strResult & "{}"
Else
strResult = strResult & "{" & vbCrLf
lngIndent = lngIndent + lngStep
arrKeys = varElement.Keys
For lngIndex = 0 To UBound(arrKeys)
strResult = strResult & String(lngIndent, strIndent) & """" & arrKeys(lngIndex) & """" & ": "
Traverse strResult, lngIndent, varElement(arrKeys(lngIndex)), strIndent, lngStep
If Not (lngIndex = UBound(arrKeys)) Then strResult = strResult & ","
strResult = strResult & vbCrLf
Next
lngIndent = lngIndent - lngStep
strResult = strResult & String(lngIndent, strIndent) & "}"
End If
Case strVarType >= vbArray
If UBound(varElement) = -1 Then
strResult = strResult & "[]"
Else
strResult = strResult & "[" & vbCrLf
lngIndent = lngIndent + lngStep
For lngIndex = 0 To UBound(varElement)
strResult = strResult & String(lngIndent, strIndent)
Traverse strResult, lngIndent, varElement(lngIndex), strIndent, lngStep
If Not (lngIndex = UBound(varElement)) Then strResult = strResult & ","
strResult = strResult & vbCrLf
Next
lngIndent = lngIndent - lngStep
strResult = strResult & String(lngIndent, strIndent) & "]"
End If
Case strVarType = vbInteger Or strVarType = vbLong
strResult = strResult & varElement
Case strVarType = vbSingle Or strVarType = vbDouble
strResult = strResult & Replace(varElement, ",", ".")
Case strVarType = vbNull
strResult = strResult & "Null"
Case strVarType = vbBoolean
If varElement Then
strResult = strResult & "True"
Else
strResult = strResult & "False"
End If
Case Else
strTemp = Replace(varElement, "\""", """")
strTemp = Replace(strTemp, "\", "\\")
strTemp = Replace(strTemp, "/", "\/")
strTemp = Replace(strTemp, Chr(8), "\b")
strTemp = Replace(strTemp, Chr(12), "\f")
strTemp = Replace(strTemp, vbLf, "\n")
strTemp = Replace(strTemp, vbCr, "\r")
strTemp = Replace(strTemp, vbTab, "\t")
strResult = strResult & """" & strTemp & """"
End Select
End Sub
Function ReadFromFile(strPath, intFormat)
With CreateObject("Scripting.FileSystemObject").OpenTextFile(strPath, 1, False, intFormat)
ReadFromFile = ""
If Not .AtEndOfStream Then ReadFromFile = .ReadAll
.Close
End With
End Function
Sub WriteToFile(strCont, strPath, intFormat)
With CreateObject("Scripting.FileSystemObject").OpenTextFile(strPath, 2, True, intFormat)
.Write(strCont)
.Close
End With
End Sub
So, save this script as .vbs file, and make all steps in my answer by the above link.
I've tested it on the JSON sample:
[
{
"display": "HTML Tutorial",
"url": "http:\/\/www.w3schools.com\/html\/default.asp"
},
{
"display": "CSS Tutorial",
"url": "http:\/\/www.w3schools.com\/css\/default.asp"
},
{
"display": "JavaScript Tutorial",
"url": "http:\/\/www.w3schools.com\/js\/default.asp"
},
{
"display": "jQuery Tutorial",
"url": "http:\/\/www.w3schools.com\/jquery\/default.asp"
},
{
"display": "JSON Tutorial",
"url": "http:\/\/www.w3schools.com\/json\/default.asp"
},
{
"display": "AJAX Tutorial",
"url": "http:\/\/www.w3schools.com\/ajax\/default.asp"
},
{
"display": "SQL Tutorial",
"url": "http:\/\/www.w3schools.com\/sql\/default.asp"
},
{
"display": "PHP Tutorial",
"url": "http:\/\/www.w3schools.com\/php\/default.asp"
},
{
"display": "XML Tutorial",
"url": "http:\/\/www.w3schools.com\/xml\/default.asp"
}
]
After processing the "item" property appears in each object of the array. Note that the source JSON string is serialized according to ECMA-404 The JSON Data Interchange Standard, thus you may find some difference from the source formatting.
[
{
"display": "HTML Tutorial",
"url": "http:\/\/www.w3schools.com\/html\/default.asp",
"item": 0
},
{
"display": "CSS Tutorial",
"url": "http:\/\/www.w3schools.com\/css\/default.asp",
"item": 1
},
{
"display": "JavaScript Tutorial",
"url": "http:\/\/www.w3schools.com\/js\/default.asp",
"item": 2
},
{
"display": "jQuery Tutorial",
"url": "http:\/\/www.w3schools.com\/jquery\/default.asp",
"item": 3
},
{
"display": "JSON Tutorial",
"url": "http:\/\/www.w3schools.com\/json\/default.asp",
"item": 4
},
{
"display": "AJAX Tutorial",
"url": "http:\/\/www.w3schools.com\/ajax\/default.asp",
"item": 5
},
{
"display": "SQL Tutorial",
"url": "http:\/\/www.w3schools.com\/sql\/default.asp",
"item": 6
},
{
"display": "PHP Tutorial",
"url": "http:\/\/www.w3schools.com\/php\/default.asp",
"item": 7
},
{
"display": "XML Tutorial",
"url": "http:\/\/www.w3schools.com\/xml\/default.asp",
"item": 8
}
]
In spite of the fact that the item addition algorithm hardcoded in the script, it can be easily extended with a dialog for options set up via lightweight mshta
GUI. If that approach meets your requirements, than let me know what options you want to be implemented within GUI, more complex modifications, etc.
Usually, yes. NP++ is surprisingly smart in handling regular expression-based replacements. In this case, it depends on further specification of exactly what should be inserted and exactly where. – Gombai Sándor – 2016-03-03T07:45:13.207
Please add something that shows the file after the change. – DavidPostill – 2016-03-03T16:12:26.110