メインコンテンツへ移動

XMLをJSONに変換

XML to JSON converts a document in your browser. There is no canonical mapping between the two formats, so every decision is an option rather than a silent default — the important one is the force-array list, because XML cannot distinguish a one-item list from a single value and no converter can infer it.

端末内で処理

このツールの画面は英語表記です。

XML
0 B1 lineLn 1, Col 1
JSONread-only
0 B1 line

以下の解説は英語のみでご覧いただけます。

How does XML to JSON work?

XML and JSON do not describe the same shapes, so there is no single correct translation between them. A converter that presents one anyway is hiding four decisions, each of which can quietly corrupt your data.

The single-element problem, which cannot be inferred

XML has no arrays. <line/><line/> is two elements; <line/> is one. So a converter turns repeated elements into an array and leaves a lone element as a scalar — which means the same endpoint produces {"line": {…}} for an order with one line and {"line": [{…}, {…}]} for an order with two. Code written against the second crashes on the first, in production, on the day a customer orders one thing.

This is not solvable by inference. The information needed — is this element a collection? — lives in the schema, not the instance. The honest fix is the force-array list: name the elements that are collections and they are always arrays, however many of them the document happens to contain today.

Attributes need somewhere to go

<line sku="X"><sku>Y</sku></line> has an attribute and a child element with the same name. Merging them loses one. The prefix — @ by default — keeps both, at the cost of keys that are slightly awkward to type in JavaScript. Set it to empty to merge them and accept the collision.

XML has no types

<qty>3</qty> is the string "3". Coercing it to a number is a guess, and it is the guess that turns the part number 007 into 7 and the postcode 01970 into 1970. Value parsing is therefore off by default, and when it is on, a leading zero still keeps the value a string — the JSON grammar forbids leading zeros anyway, so there is nothing to lose.

Mixed content does not survive

<p>before<b>bold</b>after</p> has text before and after a child. JSON objects have no ordering, so the two text runs are joined under one key and their position relative to <b> is lost. Nothing can fix this; document-shaped XML is not data-shaped, and converting it to JSON is the wrong move rather than a lossy one.

Malformed input is rejected, not guessed at

Mismatched tags and unclosed elements produce an error naming the tag and the line. A converter that accepts <a><b></a> and emits plausible-looking JSON is worse than one that fails, because the person pasting truncated XML never finds out it was truncated.

XML

<order id="1">
  <line sku="A">Widget</line>
</order>

JSON

{
  "order": {
    "@id": "1",
    "line": {
      "@sku": "A",
      "#text": "Widget"
    }
  }
}
// with "line" forced: "line": [ … ]

What options and edge cases does XML to JSON support?

Options and mapping rules
ParameterTypeDefaultBehaviour & edge cases
Force arrayelement names(none)Names listed here are always arrays, even with one occurrence. The single most important option: it is the only fix for the one-item-list problem, and it cannot be inferred from the document.
Attribute prefixstring@Keeps attributes distinct from child elements of the same name. Set it to empty to merge them, accepting that one wins on a collision.
Text keystring#textWhere an element's text goes when it also has attributes or children. An element with only text collapses to a bare string instead.
Parse valuesbooleanoffCoerces "3" to 3, "true" to true and "null" to null. Off by default because XML has no types and guessing turns part numbers into integers.
Leading zeroskept as stringalways007 stays "007" even with value parsing on. The JSON grammar forbids a leading zero, so there is no representation to convert to that keeps it.
Strip namespacesbooleanoffDrops prefixes, so soap:Envelope becomes Envelope, and removes xmlns declarations. Convenient for SOAP; lossy if two namespaces use the same local name.
Keep commentsbooleanoffPreserves comments under a #comment member. Their position between elements is not preserved, because JSON objects have no ordering.
Empty elementsnullalways<a/> and <a></a> are the same thing in XML, and both become null rather than an empty string, which would imply a value.
CDATAliteral text—Content inside CDATA is taken verbatim: an &lt; inside it is an ampersand followed by lt, not a less-than sign. That is what CDATA is for.
Entitiesdecodedthe five predefined&amp; &lt; &gt; &quot; &apos; plus numeric references. An undeclared entity is left verbatim rather than deleted, because deleting content silently is the worse failure.

Frequently asked questions

Why is one item an object but two items an array?

Because XML has no arrays, and this is the single biggest hazard when converting it. A converter sees one <line> and cannot know whether the schema allows more. Put the element name in the force-array box and it becomes an array every time, which is what your code needs to be written against. This is worth doing before you ship, not after a one-item order breaks production.

Why do my keys start with @?

Those are attributes. XML has two kinds of member and JSON has one, so attributes need a prefix or they collide with child elements — and an element with both a sku attribute and a sku child is not unusual. You can set the prefix to empty to merge them, or change it to something friendlier like an underscore.

Why are my numbers strings?

Because in XML they are strings. There is no type information in the document, so converting <qty>3</qty> to the number 3 is a guess that happens to be right for quantities and wrong for part numbers, postcodes and phone numbers. Turn value parsing on if your data has no zero-padded identifiers in it; even then, a leading zero keeps the value a string.

What happened to the text around my child elements?

It was joined and put under the text key, and its position was lost. This is mixed content, and JSON genuinely cannot represent it: an object has no ordering, so there is nowhere to record that some text came before a child and some after. If your XML is document-shaped — XHTML, DocBook, anything with markup inside prose — converting it to JSON is the wrong operation rather than a lossy one.

Can it handle SOAP responses?

Yes, and turn on strip namespaces, which is what makes soap:Envelope into Envelope and removes the xmlns declarations that would otherwise appear as attributes on every element. Be aware that stripping is lossy if the document genuinely uses two namespaces with the same local name, which is rare in SOAP and common in mixed-vocabulary XML.

Is my XML uploaded?

No. The tokenizer and the converter both run in the tab you already have open — check the Network panel. It matters because XML on the wire today is mostly SOAP, SAML assertions and financial messages, which is to say some of the most sensitive material a developer handles.