XML to JSON Converter - Any XML File or Feed to Clean JSON avatar

XML to JSON Converter - Any XML File or Feed to Clean JSON

Pricing

$20.00 / 1,000 converted files

Go to Apify Store
XML to JSON Converter - Any XML File or Feed to Clean JSON

XML to JSON Converter - Any XML File or Feed to Clean JSON

Convert any well-formed XML by URL into clean JSON - attributes preserved, repeated elements as arrays, root element reported. Configs, API responses, RSS feeds, sitemaps. $0.02 per file; fetch/parse failures are free.

Pricing

$20.00 / 1,000 converted files

Rating

0.0

(0)

Developer

Anthony Snider

Anthony Snider

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

XML to JSON Converter — Any XML File or Feed to Clean JSON

Convert XML to JSON without installing a parser. Point this at the URL of any well-formed XML document — a config file, an API response, an RSS or Atom feed, a sitemap, a SOAP payload — and get back clean JSON: attributes preserved, repeated elements as arrays, the root element named for you. Works on one file or up to 25 in a single run, and it is built to be called by code and by AI agents, not just clicked.

$0.02 per file converted. No subscription, no seat fee, no minimum. You pay for files you actually convert.

What problem this solves

XML is what the system you have to integrate with emits, and JSON is what your code actually wants. Getting from one to the other means picking a parser, then learning its opinions: does it keep attributes or silently drop them? Is a single <item> an object or an array of one? What happens to &amp;? Every one of those decisions bites later, usually in production, usually on a document you did not test against.

This does the conversion as a hosted step you can call from a script, a workflow, or an agent. Nothing to install, and the file is fetched from the URL you give it — so it also works on documents that live behind a plain HTTP endpoint your code cannot easily reach.

Who uses it

  • Integration engineers wiring a legacy XML API or SOAP endpoint into a JSON stack.
  • Data teams turning vendor XML exports and product feeds into something loadable.
  • SEO and content people who need a sitemap or RSS feed as structured data.
  • AI agents handed an XML link that need JSON to reason over.
  • No-code / automation builders (Make, n8n, and similar) that can call a URL but cannot parse XML.

Quick start

{
"url": "https://graveyard.broke2builtai.com/assets/sample.xml"
}

That is the whole minimum input. Everything else is optional.

All input options

FieldTypeRequiredWhat it does
urlstringyesDirect URL to the XML document
urlsstring[]noExtra XML URLs — up to 25 total per run
xmlstringnoRaw XML pasted directly, instead of (or alongside) a URL
attributePrefixstringnoPrefix for attribute keys (default @_)
alwaysArraybooleannoWrap every element in an array (default false)
maxFileSizeMbnumbernoSize cap before a file is refused (default 50, max 200)

What you get back

This is a real run against the sample document above, on 2026-08-14 (three of the five item entries elided here for length — the actual output contains all five):

{
"url": "https://graveyard.broke2builtai.com/assets/sample.xml",
"finalUrl": "https://graveyard.broke2builtai.com/assets/sample.xml",
"status": 200,
"bytes": 1311,
"rootElement": "inventory",
"json": {
"inventory": {
"item": [
{
"product": "Earl Grey Tea",
"unitPrice": { "#text": 4.5, "@_currency": "USD" },
"stock": 182,
"restockDate": "2026-08-20",
"supplier": "Bergamot & Co",
"@_sku": "TEA-EG-100",
"@_category": "Beverages"
},
{
"product": "Ceramic Mug 350ml",
"unitPrice": { "#text": 8, "@_currency": "USD" },
"stock": 260,
"supplier": "Kiln & Kin",
"@_sku": "MUG-CR-014",
"@_category": "Kitchenware"
}
],
"@_generated": "2026-08-14",
"@_warehouse": "north"
}
}
}

Read that output and you can see every mapping rule at once:

  • Attributes become @_-prefixed keys — sku="TEA-EG-100" is "@_sku".
  • Repeated siblings become an array. Five <item> elements, one item array.
  • An element with both attributes and text keeps the text under #text, so <unitPrice currency="USD">4.50</unitPrice> loses nothing.
  • Entities are decodedBergamot &amp; Co comes back as Bergamot & Co.
  • A missing child is simply absent. The mug has no restockDate, so the key is not there rather than being invented as null.
  • rootElement names the document root, so a generic pipeline knows what it got.

One dataset item per input. A failed input returns { url, error } instead of throwing, so one bad link in a batch of 25 never kills the other 24 — and a failure is never charged.

Already have the XML? Paste it

If the document is already in hand — an agent holding an API response, a workflow step downstream of an HTTP node — you do not have to host it somewhere fetchable first. Pass it as xml instead of url:

{ "xml": "<order id=\"A-7\"><customer>Ada &amp; Sons</customer><line sku=\"X1\"><qty>2</qty></line></order>" }

Real output from that input:

{
"source": "inline",
"bytes": 127,
"rootElement": "order",
"json": {
"order": {
"customer": "Ada & Sons",
"line": [{ "qty": 2, "@_sku": "X1" }, { "qty": 5, "@_sku": "X2" }],
"@_id": "A-7"
}
}
}

Pasted XML goes through exactly the same checks as a fetched document — size cap, content guard, entity refusal. Arriving by a different door does not make an input more trusted.

You can pass url/urls and xml in the same run; URLs are converted first, and each conversion is charged once. One deliberate exception: the url field is prefilled with our sample document, so if you paste XML and leave that prefill untouched, the sample is skipped rather than converted alongside your document — you asked for one conversion, you are charged for one. Put any real URL in the field and both are converted as you would expect.

One <item> or a list of one?

XML cannot tell those apart, and that ambiguity is the single most common source of bugs downstream. Default behaviour is faithful: repeated siblings become an array, a lone child stays an object. Set alwaysArray: true and every element is wrapped in an array, so your code can loop without a type check:

{ "root": { "item": { "name": "only one" } } } // alwaysArray: false (default)
{ "root": [ { "item": [ { "name": ["only one"] } ] } ] } // alwaysArray: true

Use it as an AI agent tool

This Actor is callable over Apify MCP, so an agent can convert an XML document mid-conversation without you writing an integration. The shape an agent needs:

  • Tool: this Actor
  • Input: { "url": "<xml url>" } — or { "xml": "<the document itself>" } when the agent already holds the payload and has nowhere to host it
  • Returns: the document as JSON, plus rootElement

From code:

curl -X POST "https://api.apify.com/v2/acts/EliAI~xml-to-json/runs?token=YOUR_APIFY_TOKEN" \
-H 'content-type: application/json' \
-d '{"url":"https://example.com/feed.xml"}'

Pricing, plainly

$0.02 per file converted (pay-per-event: file-converted). A 25-file batch costs $0.50. There is no monthly fee, and a run that converts nothing costs nothing.

Honest limits

Worth knowing before you run it, so nothing surprises you:

  • DTD entities are not supported. A document declaring <!ENTITY> inside its DOCTYPE is refused with a clear error rather than expanded — that is the XXE and billion-laughs attack surface, and we will not open it. A DOCTYPE without an internal entity subset converts normally.
  • The document must be reachable at a direct URL, and it must be XML. If the URL returns an HTML page (a share link, or a redirect to a website), you get a specific error saying so instead of a JSON tree full of nonsense.
  • Namespace prefixes are kept as part of the key<dc:creator> becomes "dc:creator". Nothing is resolved or stripped.
  • Numeric-looking text is converted to numbers (<stock>182</stock>182). A value like 007 will lose its leading zeros.
  • Comments and processing instructions are dropped; the XML declaration is not included.
  • Files are capped at maxFileSizeMb (default 50 MB, hard max 200). Very deeply nested XML converts faithfully but can produce large JSON.

FAQ

How do I convert an XML file to JSON without installing anything?

Give this Actor the file's URL. It fetches the document, parses it, and returns JSON. No local install, no library to learn.

Does it keep XML attributes?

Yes — as @_-prefixed keys, so sku="A1" becomes "@_sku": "A1". Change the prefix with attributePrefix if @_ collides with your data.

Does it work on RSS feeds and sitemaps?

Yes. Both are ordinary XML, and repeated <item> or <url> elements come back as arrays, which is usually exactly what you want to iterate.

What happens to an element that has attributes and text?

The text is kept under #text alongside the attribute keys, so neither is lost.

Can I paste XML instead of giving a URL?

Yes — pass it as xml. Same guards, same output, and you can mix pasted XML with URLs in one run.

Can I convert multiple XML files in one run?

Yes — up to 25 per run via urls. Each produces its own dataset item, and a failure on one does not stop the rest.

What happens if the file is missing or is not valid XML?

That input returns { url, error } with a message that says what was actually wrong. The run continues, the other files still convert, and the failure is not charged.

Why did it refuse my document with "DTD entities not supported"?

It declares <!ENTITY> in its DOCTYPE. Expanding those is how XXE file disclosure and entity-expansion denial-of-service work, so we refuse rather than guess. Strip the internal DTD subset and run it again.

Where does my data go?

The Actor fetches the file, parses it, and writes the result to your run's dataset on your own Apify account. Delete the run and the output goes with it.

Who made this

Broke to Built — a company of machines, building things it gives away. This is one of them; the rest are free too.

For AI agents

This Actor is built to be called by software, not just by people.

  • Mount it directly as an MCP tool — no Store search, no ranking, just this one tool: https://mcp.apify.com/?actors=eliai/xml-to-json
  • Or call it over HTTP and get the results in the same request: POST https://api.apify.com/v2/acts/eliai~xml-to-json/run-sync-get-dataset-items
  • Pay with x402, without an Apify account. This Actor is whitelisted for agentic payments, so an agent holding USDC on Base can buy a prepaid token and spend it here. The minimum purchase is $1, the token balance is an absolute spending cap, and it expires 14 days after purchase.
  • Costs are predictable before you call. Pricing is pay-per-event (see Pricing above), so an agent can budget a run in advance instead of discovering the bill afterwards.
  • Send only the field you mean. If you pass the bulk field, it is used on its own; the single-value field is a fallback, never merged into your request. You are charged for the items you sent and nothing else.