Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save Reino17/866486cde8dae9cc30abb83b382ca4a2 to your computer and use it in GitHub Desktop.

Select an option

Save Reino17/866486cde8dae9cc30abb83b382ca4a2 to your computer and use it in GitHub Desktop.

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
    }
  ]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment