“plist 中目标格式的对象无效”将 plist 转换为 json 时出错

问题描述 投票:0回答:2

当我尝试使用

plutil -convert json -
将 Plist 转换为 JSON 时,由于输入中的对象无效,它给我一个错误。例如:

$ ioreg -rw0 -c AppleSmartBattery -a | plutil -convert json -
<stdin>: invalid object in plist for destination format

当输入包含 JSON 格式的无效对象时,如何将 Plist 转换为 JSON?

json plist
2个回答
3
投票

当 plist 包含与 6 种 JSON 类型(字符串、数字、布尔值、数组、对象、null)不兼容的数据时,就会发生这种情况。最常见(可能是唯一?)的示例是二进制数据。

Python 有一个用于解析 plist 数据的内置库,当对象与 JSON 不兼容时,它还允许我们方便地指定自定义行为以序列化为 JSON。

这让我们可以创建一个相对简单的 python 单行代码(在 shell 中使用)或一个可以在 python 代码中使用的函数,其中我们指定如何处理无法序列化为 JSON 的二进制数据。

我的首选方法是对二进制数据进行 Base64 编码,并在其前面加上

base64:
,这样当我将来需要时,数据仍然可用。这是我的 shell 单行代码,我可以将 plist 输出通过管道传输到其中:

python -c 'import plistlib,sys,json,base64; print(json.dumps(plistlib.loads(sys.stdin.read().encode("utf-8")), default=lambda o:"base64:"+base64.b64encode(o).decode("ascii")))'

这是多行编写的代码,因此您可以看到它在做什么:

import plistlib
import sys
import json
import base64

stdin_bytes = sys.stdin.read()
stdin_str = stdin_bytes.encode("utf-8")
plist_data = plistlib.loads(stdin_str)

def json_default_fn(o):
    return "base64:" + base64.b64encode(o).decode('ascii')

json_data = json.dumps(plist_data, default=json_default_fn)

print(json_data)

我的建议是将单行代码包装在 bash/zsh/sh 函数中,并将其放入您的

.bashrc
/
.zshrc
/
.profile
/等中。使其易于使用:

plist_to_json() {
  python -c 'import plistlib,sys,json,base64; print(json.dumps(plistlib.loads(sys.stdin.read().encode("utf-8")), default=lambda o:"base64:"+base64.b64encode(o).decode("ascii")))'
}

使用示例(打印 MacBook 电池信息):

$ ioreg -rw0 -c AppleSmartBattery -a | plist_to_json

请注意,如果您关心正在编码的二进制数据,则可以在 json 转储中使用不同的默认函数,例如

lambda o: "<Not Serializable>"
将二进制字段设置为固定字符串。


0
投票

正如Christopher Shroba所说:

当 plist 包含与 6 种 JSON 类型(字符串、数字、布尔值、数组、对象、null)不兼容的数据时,就会发生这种情况。最常见(可能是唯一?)的示例是二进制数据。

Plist 拥有 8 种类型(bool、integer、float、string、dictionary、array、date、data),您可以尝试 sed 与 JSON 不兼容的类型。

它对我来说效果很好:

ioreg -r -k BatteryPercent -a | sed 's/data/string/g' | plutil -convert json -o okk.json

希望可以帮到你~

© www.soinside.com 2019 - 2024. All rights reserved.