我想在PowerShell中解析JSON,但我无法使用PowerShell中可用的新V3函数。我的第一个想法是加载JSON.NET组件并用它来解析JSON字符串,但它无法正常工作。
我有这个JSON:
$json = "{""Name"": ""Apple"",
""Price"": 3.99,
""Sizes"": [
""Small"",
""Medium"",
""Large""]}"
我用此代码加载json.net组件:
[Reflection.Assembly]::LoadFile("$currentPathNewtonsoft.Json.dll”)
并试图用
对其进行解析$result = [Newtonsoft.Json.JsonConvert]::DeserializeObject($json)
现在,我希望$result["Name"]
是Apple
,但我在那里什么都没得到。有什么想法吗?
代码´$ result.containskey(" name") returns
true but
$ result.getValue(" name") returns
null`。
好吧,这就是我的工作方式,因此它可以降低到Windows 2008上的至少powershell v2。
首先,为您要使用的版本加载JSON.NET组件,我采用了.NET 3.5版本:
[Reflection.Assembly]::LoadFile("Newtonsoft.Json.dll")
我在文件中使用了JSON,因为它在我写的部署配置中使用了,因此我需要读取文件,然后解析JSON
$json = (Get-Content $FileName | Out-String) # read file
$config = [Newtonsoft.Json.Linq.JObject]::Parse($json) # parse string
现在要从config中获取值,您需要使用powershell在Hashtables/dictionaries上定义的Item
方法。因此,要获得一个简单的字符串,您将写:
Write-Host $config.Item("SomeStringKeyInJson").ToString()
如果您有一系列事情,您需要做
之类的事情$config.Item("SomeKeyToAnArray") | ForEach-Object { Write-Host $_.Item("SomeKeyInArrayItem").ToString() }
要访问您写的嵌套项目
$config.Item("SomeItem").Item("NestedItem")
这就是我用powershell中的json.net解决解析JSON的方式。
如果您到达这里并使用PowerShell 5.0,则可以在PowerShell Gallery
中可用Install-Module Newtonsoft.Json
Import-Module Newtonsoft.Json
$json = '{"test":1}'
[Newtonsoft.Json.Linq.JObject]::Parse($json)
也许这就是您所追求的:
http://poshcode.org/2930
function Convert-JsonToXml {
PARAM([Parameter(ValueFromPipeline=$true)][string[]]$json)
BEGIN {
$mStream = New-Object System.IO.MemoryStream
}
PROCESS {
$json | Write-Stream -Stream $mStream
}
END {
$mStream.Position = 0
try
{
$jsonReader = [System.Runtime.Serialization.Json.JsonReaderWriterFactory]::CreateJsonReader($mStream,[System.Xml.XmlDictionaryReaderQuotas]::Max)
$xml = New-Object Xml.XmlDocument
$xml.Load($jsonReader)
$xml
}
finally
{
$jsonReader.Close()
$mStream.Dispose()
}
}
}
function Write-Stream {
PARAM(
[Parameter(Position=0)]$stream,
[Parameter(ValueFromPipeline=$true)]$string
)
PROCESS {
$bytes = $utf8.GetBytes($string)
$stream.Write( $bytes, 0, $bytes.Length )
}
}
$json = '{
"Name": "Apple",
"Expiry": 1230422400000,
"Price": 3.99,
"Sizes": [
"Small",
"Medium",
"Large"
]
}'
Add-Type -AssemblyName System.ServiceModel.Web, System.Runtime.Serialization
$utf8 = [System.Text.Encoding]::UTF8
(convert-jsonToXml $json).innerXML
输出:
<root type="object"><Name type="string">Apple</Name><Expiry type="number">1230422
400000</Expiry><Price type="number">3.99</Price><Sizes type="array"><item type="s
tring">Small</item><item type="string">Medium</item><item type="string">Large</it
em></Sizes></root>
如果您想要名称节点:
$j=(convert-jsonToXml $json)
$j.SelectNodes("/root/Name")
或
$j |Select-Xml -XPath "/root/Name" |select -ExpandProperty node
到目前为止,没有一个答案使得在没有Token PropertyName in state ArrayStart would result in an invalid JSON object
错误的情况下进行序列化,编辑和序列化。这就是对我的工作。
假设$json
包含一个有效的JSON字符串,该字符串的必要性为hashtable:
$config = [Newtonsoft.Json.JsonConvert]::DeserializeAnonymousType($json, @{})
或,如果您需要维护密钥顺序:
$config = [Newtonsoft.Json.JsonConvert]::DeserializeAnonymousType($json, [ordered]@{})
然后,您可以将数据作为正常的标签处理,然后再次序列化。
$sb = [System.Text.StringBuilder]::new()
$sw = [System.IO.StringWriter]::new($sb)
$jw = [Newtonsoft.Json.JsonTextWriter]::new($sw)
$jw.Formatting = [Newtonsoft.Json.Formatting]::Indented
$s = [Newtonsoft.Json.JsonSerializer]::new()
$s.Serialize($jw, $config)
$json = $sb.ToString()