Let's say we have the following JSON...
{
"a": "b",
"c": [
{
"x": 1,
"y": 2,
"z": 3
}
]
}
...and we want to assign it to a %json% CMD/Batch-variable and then extract and assign the array to %array% with xidel.
No escaping
SET json={"a": "b", "c": [{"x": 1, "y": 2, "z": 3}]}
ECHO %json% | xidel - -se "$json/c"
[
{
"x": 1,
"y": 2,
"z": 3
}
]
ECHO %json% | xidel - -se "serialize-json($json/c)"
[{"x": 1, "y": 2, "z": 3}]
To assign the output of a program to a variable, a FOR-loop is needed...
FOR /F "delims=" %A IN ('ECHO %json% ^| xidel - -se "serialize-json($json/c)"') DO SET array=%A
Error:
err:FOJS0001: value not allowed at c (tkString) in {"a": "b" "c": [{"x": 1 "y": 2 "z": 3}]}
...but this is where things go wrong.
From xidel's error-message you can see it was trying to parse a JSON without commas. The comma is a special character and will disappear unless escaped with a caret ^. The same goes for the pipe-symbol |.
Escaping the comma
SET json={"a": "b"^, "c": [{"x": 1^, "y": 2^, "z": 3}]}
ECHO %json% | xidel - -se "serialize-json($json/c)"
[{"x": 1, "y": 2, "z": 3}]
FOR /F "delims=" %A IN ('ECHO %json% ^| xidel - -se "serialize-json($json/c)"') DO SET array=%A
Error:
err:FOJS0001: value not allowed at c (tkString) in {"a": "b" "c": [{"x": 1 "y": 2 "z": 3}]}
The commas in the %json%-variable are escaped with a caret ^, but they still disappeared in the FOR-loop. That's because the SET-command itself also interprets the commas as special characters, unless you double escape the comma, or wrap the assignment in double-quotes.
Double escaping the comma
The caret ^ itself is also a special character and needs to be escaped as well. So to properly escape a comma; ^^^,.
SET json={"a": "b"^^^, "c": [{"x": 1^^^, "y": 2^^^, "z": 3}]}
ECHO %json% | xidel - -se "serialize-json($json/c)"
[{"x": 1, "y": 2, "z": 3}]
FOR /F "delims=" %A IN ('ECHO %json% ^| xidel - -se "serialize-json($json/c)"') DO SET array=%A
SET array=[{"x": 1, "y": 2, "z": 3}]
Escaping the comma and wrapping the assignment in double-quotes
SET "json={"a": "b"^, "c": [{"x": 1^, "y": 2^, "z": 3}]}"
ECHO %json% | xidel - -se "serialize-json($json/c)"
[{"x": 1, "y": 2, "z": 3}]
FOR /F "delims=" %A IN ('ECHO %json% ^| xidel - -se "serialize-json($json/c)"') DO SET array=%A
SET array=[{"x": 1, "y": 2, "z": 3}]
We have our %array% variable, but because the commas aren't properly escaped, we're right back where we started.
Luckily xidel can do this for you with the option --output-format=cmd. This automatically serializes/minifies the JSON and so the function serialize-json() isn't needed anymore.
SET json={"a": "b"^^^, "c": [{"x": 1^^^, "y": 2^^^, "z": 3}]}
ECHO %json% | xidel - -se "array:=$json/c" --output-format=cmd
SET array=[{^"x^": 1^, ^"y^": 2^, ^"z^": 3}]
This is just a string. To execute this string/command put it in a FOR-loop.
FOR /F "delims=" %A IN ('ECHO %json% ^| xidel - -se "array:=$json/c" --output-format^=cmd') DO %A
SET array=[{^"x^": 1^, ^"y^": 2^, ^"z^": 3}]
ECHO %array% | xidel - -se "$json"
[
{
"x": 1,
"y": 2,
"z": 3
}
]
With --output-format=cmd all the necessary characters are automatically escaped (escaping the double-quotes wasn't necessary in this case, but wouldn't harm), so generating the initial JSON with xidel would've been a better idea:
xidel -se "{'a':'b','c':[{'x':1,'y':2,'z':3}]}"
{
"a": "b",
"c": [
{
"x": 1,
"y": 2,
"z": 3
}
]
}
FOR /F "delims=" %A IN ('xidel -se "json:={'a':'b','c':[{'x':1,'y':2,'z':3}]}" --output-format^=cmd') DO %A
SET json={^"a^": ^"b^"^, ^"c^": [{^"x^": 1^, ^"y^": 2^, ^"z^": 3}]}
ECHO %json% | xidel - -se "$json"
{
"a": "b",
"c": [
{
"x": 1,
"y": 2,
"z": 3
}
]
}