2

I'd like to add an XML file to my JSON request body in a CURL command. This is what I have right now

data=$(cat testdata.xml)
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ "data": ''"$(echo $data)"''}' 'http://...'

However this sends { data: '$(echo $data)' } } instead of actually fetching the file.

If I take out the outer single quotes around $(echo $data) like this:

data=$(cat testdata.xml)
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ "data": '"$(echo $data)"'}' 'http://...'

Then I encounter error Unexpected token < in JSON at position 10

because the server is reading

'{ "data": <?xml version="1.0" encoding="UTF-8"?> - <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don\'t forget me this weekend!</body> </note>}',

How do I fix this? Note that I do NOT want to convert to JSON first. I only want to send the stringified xml file in body.

3
  • 1
    Cramming stringified XML through the command line seems like the wrong approach. Can you use the -F option to submit it as multipart/mime, reading from a file or a pipe? Commented Dec 7, 2017 at 21:51
  • -d "{ data : \"$data\"}" Commented Dec 7, 2017 at 21:55
  • 1
    @daniu, ...works only up until your data contains literal quotes, or newlines, or other content that needs to be escaped to be valid in a JSON string. And an XML document is overwhelmingly likely to contain newlines and quotes. Commented Dec 7, 2017 at 21:56

1 Answer 1

2

As always, use jq to generate properly-escaped JSON in bash.

data=$(jq -Rs '{ "data": . }' <testdata.xml)
curl -X POST \
     --header 'Content-Type: application/json' \
     --header 'Accept: application/json' \
     -d "$data" \
     "$url"

If you don't have jq installed, you can use Python for the job, substituting the following for the line that used jq:

data=$(python -c 'import json, sys; json.dump({"data": sys.stdin.read()}, sys.stdout)' <testdata.xml)
Sign up to request clarification or add additional context in comments.

10 Comments

to use this I would need to install jq?
Yes. bash does not have facilities for correct JSON handling built-in.
@b11, ...if you can't install jq, it's easy enough to call a Python interpreter from shell to do the job (as Python also has a correct JSON parsing/generation module); I've extended the answer to cover that.
Thank you for this, when I run the Python method I noticed that the xml being attached has newline characters \n and escape slash for strings. Is there an easy way to avoid this?
@b11, avoid it? It'd be incorrect escaping if you avoided it -- either the JSON document would no longer be valid, or reading the data string attribute in a JSON parser would no longer result in a correct, parsable XML document.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.