Json文件到powershell并返回到json文件

Rom*_*nov 5 powershell json special-characters readfile writetofile

我试图在powershell中操作json文件数据并将其写回文件.甚至在操作之前,当我刚刚从文件中读取时,将它转换为powershell中的Json对象并将其写回文件,某些字符将被某些代码替换.以下是我的代码:

$jsonFileData = Get-Content $jsonFileLocation

$jsonObject = $jsonFileData | ConvertFrom-Json

... (Modify jsonObject) # Commented out this code to write back the same object

$jsonFileDataToWrite = $jsonObject | ConvertTo-Json

$jsonFileDataToWrite | Out-File $jsonFileLocation
Run Code Online (Sandbox Code Playgroud)

某些字符正在被其代码替换.例如:

< is replaced by \u003c
> is replaced by \u003e. 
' is replaced by \u0027
Run Code Online (Sandbox Code Playgroud)

样本输入:

{
    "$schema": "https://source.com/template.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "accountName": {
            "type": "string",
            "defaultValue": "<sampleAccountName>"
        },
        "accountType": {
            "type": "string",
            "defaultValue": "<sampleAccountType>"
        },
    },
    "variables": {
        "location": "sampleLocation",
        "account": "[parameters('accountName')]",
        "type": "[parameters('accountType')]",
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

{
    "$schema": "https://source.com/template.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "accountName": {
            "type": "string",
            "defaultValue": "\u003csampleAccountName\u003e"
        },
        "accountType": {
            "type": "string",
            "defaultValue": "\u003csampleAccountType\u003e"
        },
    },
    "variables": {
        "location": "sampleLocation",
        "account": "[parameters(\u0027accountName\u0027)]",
        "type": "[parameters(\u0027accountType\u0027)]",
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么会发生这种情况,我该怎么做才能让它不是替换字符并以同样的方式写回来?

Ale*_*sht 5

由于引擎ConvertTo-Json使用.NET JavaScriptSerializer,问题或多或少已在这里得到解答.

这是一些无耻的copypaste:

字符正在"正确"编码!使用有效的JSON库来正确访问JSON数据 - 它是一种有效的JSON 编码.

转义这些字符可防止通过JSON进行HTML注入 - 并使JSON XML友好.也就是说,即使JSON直接发送到JavaScript(由于JSON是JavaScript的有效2子集,也经常这样做),它不能用于提前终止元素,因为相关字符(例如<,>)是在JSON本身.


如果您确实需要将字符代码转回非转义字符,最简单的方法可能是为每个字符代码执行正则表达式替换.例:

$dReplacements = @{
    "\\u003c" = "<"
    "\\u003e" = ">"
    "\\u0027" = "'"
}

$sInFile = "infile.json"
$sOutFile = "outfile.json"

$sRawJson = Get-Content -Path $sInFile | Out-String
foreach ($oEnumerator in $dReplacements.GetEnumerator()) {
    $sRawJson = $sRawJson -replace $oEnumerator.Key, $oEnumerator.Value
}

$sRawJson | Out-File -FilePath $sOutFile
Run Code Online (Sandbox Code Playgroud)

  • _例外_,如果您将内容发布为 `application/json`,那么人们会期望 `ConvertTo-JSON` 遵循 JSON 规范,该规范指定仅控制字符、双引号 (U+0022) 和实际上需要转义的其他相对较少。任何其他角色都不会。PowerShell 的 GH 存在一个未解决的问题,当他们在 PowerShell Core 中切换到 NewtonSoftJSON 时,JSON 与 PSv5 中的不同。简而言之,PS Core 通过使用默认的 NewtonSoft.Json 字符串转义器来遵循 JSON 规范。 (2认同)