IT
OmnvertImage • Document • Network

XML ↔ JSON Converter

Convert XML to JSON or JSON to XML with configurable attribute shapes and namespaces. 100% client-side.
Developer Tools →
Attr prefix
Format
Indent
Input bytes
501
Output bytes
0
Top-level keys
0
XML input
501 chars
JSON output
0 chars
100% client-side: input never leaves your browser.
About this tool

XML is the format that most developers under 35 hope they will never have to touch and that most developers over 35 know they cannot avoid. SOAP web services, RSS feeds, sitemaps, OPML, SVG, OOXML (Office documents), Maven and Gradle build files, Spring application contexts, Android resources, Apple plist files, Java enterprise descriptors, banking message formats (ISO 20022), healthcare records (HL7 CDA), and a long tail of legacy enterprise integrations all use XML. The format has rich features that JSON does not directly express — attributes alongside text content, namespaces for vocabulary mixing, mixed content where text and elements intermix, CDATA blocks for embedding raw text, and a strict ordering of children — and converting between XML and JSON requires deciding how to represent each of those features in the other format. This tool implements a balanced convention that matches what most modern XML-to-JSON tooling expects, with the configuration knobs needed to handle the cases that come up in practice.

The XML-to-JSON direction is the harder one because the conversion involves real choices. Attributes need a place to go in the JSON shape — the convention here is to prefix them with '@' (so the XML attribute id becomes the JSON key '@id'), which keeps them visually distinct from element children. Text content inside an element that also has attributes or children needs a place too — the convention here is the key '#text' for that mixed-content case, again to be visually distinct. Self-closing elements (<empty/>) become null or empty objects depending on the configuration. Multiple sibling elements with the same name become an array (so two <user> children become [{...}, {...}] in the JSON). Namespaces are preserved by default with their prefix attached to the local name (xmlns:foo='...' produces JSON keys like 'foo:element'); the strip-namespace toggle removes them when you want a clean JSON output that does not carry the namespace structure forward.

The JSON-to-XML direction is the cleaner one because every JSON construct has a well-defined XML representation. Object keys become element names, arrays become repeated sibling elements, primitive values become text content, keys starting with '@' become attributes (matching the inverse convention), and the special key '#text' becomes mixed text content. Empty objects produce empty XML elements. Numbers and booleans serialize as their string representations (XML has no native types — everything is text; type interpretation is the consumer's job). The output is well-formed XML that round-trips cleanly back to the same JSON when run through the inverse direction.

Where this tool earns its keep. First, debugging SOAP responses or webhook payloads from legacy enterprise systems: paste the XML, get the JSON, navigate the structure with modern tools. Second, generating XML for an API that requires it from a JSON data source you already have: paste the JSON, get the XML, post it to the endpoint. Third, scraping RSS feeds or sitemaps for analysis: convert to JSON, then process with the same tools you use for everything else. Fourth, converting OPML reading lists between feed readers that disagree on import format. Fifth, inspecting OOXML or other XML-based document formats by extracting the .xml part of the archive and pasting it in. Sixth, converting Maven dependency trees into a form you can grep through more easily.

Attribute handling deserves a separate paragraph because the conventions vary. Some XML-to-JSON tools put attributes inline alongside child elements with no prefix (so id becomes a key called id, which conflicts with any child element named id); some use a separate attributes object (so attributes become element.attributes.id); some prefix with '@', '$', or '_'. The '@' convention is the most common modern choice (used by fast-xml-parser, BadgerFish convention, many JS libraries), and it is the default here. The 'no prefix' option is available when you know your XML never has attributes that conflict with child element names; the 'underscore' option (_id instead of @id) is for compatibility with older tools. Pick the convention that matches your downstream consumer.

Mixed content (text and elements interleaved inside the same parent) is the part of XML that JSON does not express well. <p>Hello, <b>world</b>!</p> has text 'Hello, ', then a <b>world</b> element, then text '!', and the text fragments are part of the structure — losing them changes the meaning. Our convention represents this as { p: { '#text': 'Hello, ', b: 'world', '#text2': '!' } } or as an array of mixed text/element fragments, depending on the option. For documents where mixed content matters (HTML-like text), the array representation is more faithful; for data-shaped XML where mixed content is a bug rather than a feature, the simpler object representation is fine. The default in this tool favors the data-shaped representation because that is what most XML inputs in modern work look like.

Namespaces are the part of XML that surprises most developers learning the format. An XML document can use multiple namespaces simultaneously (one for the document type, one for inline schemas, one for vendor extensions), and the namespaces are usually declared at the root with xmlns:prefix='URI'. Element and attribute names that use a namespace are written prefix:localName, where prefix is bound to the namespace URI. JSON does not have namespaces, so the conversion has to flatten — either by dropping the prefix (which loses the namespace info but produces clean JSON), or by keeping the prefix in the key (which preserves the structure at the cost of awkward JSON keys). The strip-namespace toggle controls this; default is to keep prefixes, because losing namespace info silently is rarely what you want.

CDATA blocks (<![CDATA[...]]>) are XML's way of embedding raw text that should not be parsed as markup. The contents are preserved literally; we expose them in the JSON as plain text content, with no marker that the original was CDATA. The reverse direction (JSON to XML) writes plain text content; if you need CDATA in the output (for embedding HTML inside an RSS feed item, for example), you can wrap the text manually post-conversion. Most consumers do not care whether the source was CDATA or escaped text, since the resulting character data is identical.

Privacy is the same model as the rest of our tools: nothing is uploaded, nothing is logged, the conversion runs entirely in your browser via fast-xml-parser. The XML or JSON you paste — including any embedded enterprise system identifiers, internal namespaces, or pre-release schemas — never leaves your device. Verify by opening the network tab during conversion. This matters meaningfully for XML, which is often the format of legacy enterprise systems where the data is sensitive by default; many online XML/JSON converters upload the input to a server, which is often forbidden by corporate policies.

Performance scales linearly with input size. A 1MB XML document converts in well under a second; a 10MB document takes a few seconds. For genuinely huge inputs (tens of megabytes), the browser tab will struggle, and you should use command-line tools (xmllint, jq with xq) instead. The everyday case of API responses, RSS feeds, or config files (typically under 1MB) is well within the browser implementation's range.

Workflow tip: for round-trip conversions (XML → JSON → XML), expect minor cosmetic differences in the output XML — attribute ordering, whitespace between elements, self-closing vs separate-close-tag form for empty elements. The semantic content is preserved (the same data is in the same shape), but the byte-for-byte form is not. For exact round-trip fidelity, use an XML-aware tool that preserves the original document object model. For most use cases, the semantic round-trip is sufficient.

The tool pairs naturally with adjacent utilities. The YAML ↔ JSON converter is the parallel utility for the YAML world. The JSON Viewer handles the JSON side once converted; the JSON Diff tool compares two XML payloads after converting both to JSON. The JSON to TypeScript generator produces types from the JSON for use in code. The SVG Tools handles the special case of SVG, which is XML-shaped but has its own dedicated tooling. Together, these cover most of the format-juggling work that comes up when bridging legacy XML systems and modern JSON-based pipelines.

Use cases
  • Debug SOAP responses from legacy enterprise systems by converting to JSON.
  • Generate XML for APIs that require it from JSON data you already have.
  • Scrape RSS feeds or sitemaps for analysis in JSON-based tools.
  • Convert OPML reading lists between feed readers.
  • Inspect OOXML / DOCX / XLSX internal XML by pasting the extracted parts.
  • Convert Maven dependency trees into a form you can grep through.
  • Round-trip an XML config to normalize attribute ordering and whitespace.
  • Teach the XML/JSON mapping by converting back and forth in real time.
How it works
  1. 1Pick a direction: XML → JSON or JSON → XML.
  2. 2Paste the source on the left, or upload an .xml / .json file.
  3. 3Tweak the conversion: attribute prefix (@ / _ / none), namespace handling, indent.
  4. 4Watch the converted output update on the right.
  5. 5Use the swap button to flip directions and round-trip.
  6. 6Click Copy or Download .json / .xml to grab the result.
FAQ
How are XML attributes represented in JSON?
By default with an '@' prefix — XML attribute id becomes JSON key '@id'. Configurable to '_' prefix or 'no prefix' depending on what your downstream consumer expects.
What happens to namespaces?
By default they are preserved with prefix:localName as the JSON key. The strip-namespace toggle removes them when you want clean JSON without namespace prefixes.
How is mixed content handled?
Text content alongside child elements uses a '#text' key. For elements where ordering of mixed text and child fragments matters, the array representation preserves order; for data-shaped XML the simpler object form is used.
Is CDATA preserved as CDATA?
The text contents are preserved verbatim, but the JSON output represents it as plain text with no CDATA marker. The reverse direction emits plain text; if you need CDATA in the output XML, wrap it post-conversion.
What about multiple sibling elements with the same name?
They become a JSON array. <users><user>a</user><user>b</user></users> becomes { users: { user: ['a', 'b'] } }. Single elements stay as single values.
Will it parse SOAP envelopes?
Yes — SOAP is just XML with a particular namespace structure. The Envelope, Header, and Body elements parse normally; the namespaces are preserved unless you strip them.
Is my XML/JSON sent to a server?
No. Conversion runs entirely in your browser via fast-xml-parser. Verify in the network tab — no outbound requests.
Will the round-trip preserve byte-for-byte XML?
Probably not — attribute ordering, whitespace between elements, and self-closing-tag form may differ. The semantic content (the data and its structure) is preserved. For byte-exact round-trip, use a DOM-preserving XML editor.