Add new element to all items in json file

0

1

I have json array in a file:

[
   {
        "id": 2,
        "title": "Mr",  
        "name": "Harry Robinson",
        "company": "ResearchBch",
        "email": "anything",
        "age": 38,
        "startDate": "2015/07/25",
        "salary": "$421069.74"
    },
    ...
]

I want to add new item to each item in that array. Is there any tools or text redactors, plugins for Notepad++ I can use in order to do that?

Lets say I want to insert new property "string": "bla" to each json item.

Any thoughts?

sreginogemoh

Posted 2016-03-03T07:07:11.680

Reputation: 159

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

Answers

2

Provided that the above format always applies:

Ctrl-H
Find what: ([\r\n]+)(\s+)\}
Replace with: ,\1\2\2"string": "bla"\1\2}

Gombai Sándor

Posted 2016-03-03T07:07:11.680

Reputation: 3 325

0

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.

omegastripes

Posted 2016-03-03T07:07:11.680

Reputation: 353