漂亮的打印xml包含在JSON中

时间:2015-05-26 15:49:11

标签: xml jq

来自应用程序的日志消息符合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?

1 个答案:

答案 0 :(得分:2)

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

$ 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>