向 json 文件中的所有项目添加新元素

向 json 文件中的所有项目添加新元素

我有一个文件中的 json 数组:

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

我想向该数组中的每个项目添加新项目。是否有任何工具或文本编辑器、Notepad++ 插件可用于执行此操作?

假设我想"string": "bla"向每个 json 项插入新属性。

有什么想法吗?

答案1

假设上述格式始终适用:

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

答案2

我已经通过链接描述了一种使用 WSH VB 脚本在 Notepad++ 中自动执行操作的方法:在 Notepad++ 中搜索并用结果替换数学运算。该方法允许您为自动操作分配键盘快捷键,并将必要的命令添加到脚本以处理正在编辑的文件。有代码向数组中的每个对象添加一个属性,以 JSON 文件表示:

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

因此,将此脚本保存为.vbs 文件,并按照上面的链接执行我的答案中的所有步骤。

我已经在 J​​SON 示例上进行了测试:

[
    {
        "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"
    }
]

处理后,“item”属性出现在数组的每个对象中。请注意,源 JSON 字符串是根据以下方式序列化的:ECMA-404 JSON 数据交换标准,因此您可能会发现与源格式有些不同。

[
    {
        "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
    }
]

尽管项目添加算法在脚本中是硬编码的,但它可以通过轻量级mshtaGUI 设置选项对话框轻松扩展。如果该方法满足您的要求,请告诉我您希望在 GUI 中实现哪些选项、更复杂的修改等。

相关内容