Cookies for analytics and advertising
We use cookies for analytics and advertising, both sent to Google. Refusing changes nothing you can see.Read the privacy page
Converting XML to JSON here uses one consistent convention: attributes become keys prefixed with @, an element own text becomes #text, and repeated sibling elements become an array. The catch worth knowing before you write code against it is that repetition is data, not schema — one item gives you an object and two give you an array.
Up to 100 files at once. Mixed formats are fine.
They convert one after another and download together as a ZIP.
XML to JSON
XML carries information in three places — element names, attributes and text — and JSON has only keys and values, so the mapping needs a convention. This one is the common one: each element becomes a key whose value is an object of its children, each attribute becomes a key on that same object prefixed with @, and an element own text, where it has children or attributes alongside it, is stored under the key #text.
An element with nothing but text is simpler: it becomes a plain string value with no wrapper object at all. That inconsistency is unavoidable, and it is worth internalising early, because it means the value at a given path is sometimes a string and sometimes an object depending on whether the source element happened to carry an attribute.
This is the single most expensive thing about consuming converted XML. An XML document does not say which elements repeat — only a schema says that, and the parser is not reading one. So a channel containing one item element produces an object, and a channel containing two produces an array of objects. The shape of your JSON depends on how much data was in the file.
Code written against a full RSS feed therefore breaks on the day the feed has one entry, and code written against a SOAP response with a single record breaks the first time two come back. There is no option here that fixes it, because fixing it requires knowing the schema. Write the consumer to accept both: coerce every collection to an array as the first thing you do, before any other logic touches it.
A SOAP envelope arrives with its prefixes intact: soap:Envelope becomes a key literally named "soap:Envelope", and the namespace declarations come through as attributes such as "@xmlns:soap". Nothing is resolved and nothing is stripped.
That is faithful and it is fragile, because a prefix is arbitrary. A service that emits soapenv:Envelope one week and soap:Envelope the next has produced two equivalent documents and two incompatible JSON structures. If you control the consumer, match on the local name after the colon rather than on the full key, and never hard-code a prefix you did not define yourself.
A document that opens with a version and encoding declaration produces a top-level key named "?xml" holding its attributes, sitting next to the root element key. It is not part of the document content and it is in your JSON.
Handle it by ignoring it or by deleting it, but do not assume the root element is the only top-level key. Code that reads the first key of the object to find the root will find the declaration instead on any document that has one, which is most of them.
Values that look numeric become JSON numbers, in attributes and in element text alike. A version attribute written 1.0 becomes 1. An identifier written 007 becomes 7. A zero-padded element value written 0755 becomes 755.
That is convenient for a count and destructive for anything you were treating as an opaque token. Order numbers, product codes, postcodes, protocol versions and file modes all fail the same way, and none of them raise an error. The habit worth building is to look at every attribute in the output that you intend to compare as a string, once, before the code that reads it exists — this is much cheaper than finding out from a support ticket that order 007 and order 7 are the same order.
Comments are dropped without trace, which on a payload is usually harmless and on a config file is a real loss. CDATA is unwrapped: whatever was inside the section becomes an ordinary string, so an HTML fragment wrapped in CDATA — the normal way an RSS feed carries a post body — comes through as text containing angle brackets, and converting back to XML would escape it rather than restore the CDATA section.
Mixed content is the case with no good answer. An element containing text, then a child element, then more text keeps the child under its own key and concatenates the two text runs into a single #text value, with no marker for where the child sat between them. Any document where prose and markup interleave — XHTML, DocBook, anything narrative — loses its ordering here, and JSON is simply the wrong destination for it.
A self-closing element and an element with an empty body both become an empty string. XML makes no distinction between them either, so nothing has been lost, but JSON has null available and it is not used — an empty element is "" and not null.
The distinction that does disappear is between an element that was absent and one that was present and empty, once your code applies a default. Both end up falsy. Where the difference matters — an optional field explicitly cleared versus never set — check for the key rather than for its value.
Put together, a SOAP response reads as nested keys: the envelope key, the body key inside it, then the operation response, then the payload. Every level keeps its prefix and the whole thing is three or four objects deep before any of your data appears, which is exactly as verbose as the XML was and easier to walk from code.
A fault is the case to test first. SOAP faults use a different element structure from a successful response, so the JSON for an error looks nothing like the JSON for a result, and a client that only ever saw the happy path will read undefined off a path that no longer exists. Convert one real fault response here and write the error branch against it before you need it.
The output is indented two spaces, so it reads well in a review and pastes into a test fixture directly. Fixtures are the right use for it: converting one real response and checking it into the repository gives the consumer something honest to be tested against, including all the awkwardness above.
Three defensive habits cover almost every problem on this page. Normalise anything that can repeat into an array. Compare identifiers as strings, and convert them back to strings at the boundary if the parser made them numbers. Match namespaced keys on their local part. With those in place the conversion is reliable, and everything else it does is predictable.
| XML | JSON | |
|---|---|---|
| Full name | Extensible Markup Language | JavaScript Object Notation |
| File extension | .xml | .json |
| Media type | application/xml | application/json |
| First published | 1998 | 2001 |
| Published by | W3C | — |
| Specification | XML 1.0 | RFC 8259 |
| Licensing | Open standard | Open standard |
| Standing today | Current | Current |
| Opens in a browser | Every browser | Every browser |
| Considered instead | YAML | YAML, NDJSON |
Comments do not survive. XML lets you annotate a file and JSON has no syntax for it, so every explanatory line is dropped — which matters most on exactly the files people comment: configuration somebody else has to maintain.
Visual Studio Code reads both XML and JSON, so there is a way to check the result against the original without a second tool.
XML is W3C's format, published in 1998. The specification is XML 1.0, and it is worth reading if the file has to outlive the tool that wrote it.
JSON dates from 2001, specified as RFC 8259. Visual Studio Code, jq and Postman all read it.
No. This conversion runs entirely inside your browser, so the file never leaves your device. You can confirm it yourself: open the network tab of your browser's developer tools and convert something. You will see the page load, plus the analytics and advertising the site is paid for with — and nothing carrying your file.
As keys prefixed with @ on the same object as the child elements. An element written with id="42" produces a key named "@id". An element that has both attributes and text gets its text under a key named "#text".
Because XML has no way to say that an element repeats. The parser cannot know a single
The prefix stays part of the key name, so soap:Envelope becomes a key literally called "soap:Envelope". The xmlns declarations survive as attribute keys such as "@xmlns:soap". Nothing is resolved, so two documents using different prefixes for the same namespace produce different JSON.
Attribute values are parsed, so version="1.0" becomes 1 and id="007" becomes 7. That is fine for counts and wrong for identifiers and versions. Check any attribute you treat as an opaque string before relying on the output.
Comments are dropped entirely. CDATA is unwrapped, so its contents become an ordinary string — the markup inside it is text, not structure, and it will be escaped again if you convert back to XML.
No. The parser and the serialiser both run in this page in JavaScript, so a customer record or a signed response stays on your machine. The free tier accepts files up to 100 MB.
This page converts one into the other. If you are choosing rather than converting, XML vs JSON answers which to use, for what, and what each is bad at.