漂亮的印刷品 xml 包裹在 JSON 中

Pretty print xml encased in JSON

来自应用程序的日志消息符合 LogStash 的期望 (JSON),但我们还没有在所有情况下启动 LogStash 和 运行,所以我一直在努力学习使用jq 在 LogStash 不可用时读取输出。当 JSON 中的输出为 XML 时,问题就变得棘手了。我得到这样的输出...

{
    <SNIP>
    "rom_response_body": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<OrderCreateResponse xmlns=\"http://api.example.com/schema/checkout/1.0\">\n   <ResponseStatus>Success</ResponseStatus>\n   <ResponseDescription>CustomerOrderId = 0005410600539 , OrderUUID = 57c27a87-2f2e-41d1-bc20-afef511b91aa</ResponseDescription>\n</OrderCreateResponse>",
    <SNIP>
}

我想得到的是:

<?xml version="1.0" encoding="UTF-8"?>
<OrderCreateResponse xmlns="http://api.example.com/schema/checkout/1.0">
    <ResponseStatus>Success</ResponseStatus>
    <ResponseDescription>CustomerOrderId = 0005410600541 , OrderUUID = 3bc76558-f5aa-4e2e-866d-5c4707e873db</ResponseDescription>
</OrderCreateResponse>

或者至少是任何原始形式的格式良好的 xml(从那时起我可以使用 xmllint)。我可以 sorta 和 jq 一起到达那里。如果我这样做

tail system.log | jq "select(.rom_response_body)|.rom_response_body|fromjson"

我得到错误输出像

jq: error: Invalid numeric literal at line 1, column 6 (while parsing '<?xml version="1.0" encoding="UTF-8"?>
<OrderCreateResponse xmlns="http://api.example.com/schema/checkout/1.0">
   <ResponseStatus>Success</ResponseStatus>
   <ResponseDescription>CustomerOrderId = 0005410600541 , OrderUUID = 3bc76558-f5aa-4e2e-866d-5c4707e873db</ResponseDescription>
</OrderCreateResponse>')

我认为问题在于输入实际上不是 json,它只是一个 json 转义字符串文字。如果用 {"key": } 包裹,它将是有效的。除了手动包装每一行以使其完整之外,是否有更明智的方法来获取我需要的输出 JSON?

默认输出格式是一个或多个有效的 JSON 值。 XML 显然不是 JSON。然而,字符串本身是有效的,但它所代表的值却不是。您可以使用原始输出选项 (-r) 忽略此限制。这将 return 字符串的值。

$ tail system.log | jq -r '.rom_response_body'
<?xml version="1.0" encoding="UTF-8"?>
<OrderCreateResponse xmlns="http://api.example.com/schema/checkout/1.0">
   <ResponseStatus>Success</ResponseStatus>
   <ResponseDescription>CustomerOrderId = 0005410600539 , OrderUUID = 57c27a87-2f2e-41d1-bc20-afef511b91aa</ResponseDescription>
</OrderCreateResponse>