What an XML parser turns your document into
An XML parser reads markup and hands your program a data structure. In JavaScript that is usually a plain object, and the rules for how XML becomes an object decide how you write every line that reads it. This XML parser shows you that object as an expandable tree, so you can check the shape before writing response.order.item[0] and discovering it is not an array.
The parsing is done with fast-xml-parser, a widely used JavaScript library, configured to keep attributes.
The mapping rules, by example
<order id="42">
<customer vip="yes">Ava</customer>
<item sku="A1">Mouse</item>
<item sku="B7">Pad</item>
<empty/>
<qty>007</qty>
</order>
parses to:
{
"order": {
"@id": "42",
"customer": { "@vip": "yes", "#text": "Ava" },
"item": [
{ "@sku": "A1", "#text": "Mouse" },
{ "@sku": "B7", "#text": "Pad" }
],
"empty": "",
"qty": "007"
}
}
| XML | Parsed as |
|---|---|
Attribute id="42" | Key with the prefix: "@id": "42" |
| Element with only text | A plain string value |
| Element with text and attributes | Object with the text under #text |
| Element repeated under one parent | An array |
| Empty element | Empty string "" |
| Numbers, booleans | Strings, exactly as written ("007" keeps its zeros) |
| CDATA section | Its content, merged into the text |
| Declaration, processing instructions, comments | Left out |
The attribute prefix option
Attribute prefix in tree controls how attribute keys are marked. The default @ matches many XML-to-JSON conventions. Enter _ and you get _id; enter @_ to mirror fast-xml-parser's own default. If you clear the field, attributes become ordinary keys and are indistinguishable from child elements, which is only safe when names never collide.
Pitfalls to plan for in code
- One or many. A single
<item>parses to an object, two parse to an array. Code that loops overorder.itemmust handle both; most libraries offer an "always array" setting for known list elements. - Mixed content loses its order.
<note>Leave at <b>door</b> ok</note>parses to{"b": "door", "#text": "Leave atok"}. Object-style parsing is meant for data, not prose; use a DOM parser for documents like XHTML. - Everything is a string. Convert numbers and booleans yourself, which also protects IDs and ZIP codes with leading zeros.
- Namespace prefixes stay in the key.
<soap:Body>becomes the keysoap:Body.
The same result in your own code
If your project uses fast-xml-parser, these options produce a very similar object (this page additionally lists attributes before child elements):
import { XMLParser } from 'fast-xml-parser';
const parser = new XMLParser({
ignoreAttributes: false,
attributeNamePrefix: '@',
parseTagValue: false,
ignoreDeclaration: true,
});
const data = parser.parse(xmlText);
Parse errors
Only well-formed XML is parsed. Otherwise the status bar shows the reason and position, for example Attribute 'id' is without value for <b id=1>. The XML validator explains the common causes.
Next steps
To get the parsed structure as a JSON document you can save, use XML to JSON. To generate type definitions for it, try XML to TypeScript. If you only need a few values, an expression in the XPath tester is often simpler than walking the object.
Privacy
Parsing runs in your browser and your XML is not uploaded. Load URL fetches through our server, and Save & Share stores the input on our server for the link.
XML parser in Python
Python's standard XML parser is xml.etree.ElementTree. ET.fromstring() parses a string and ET.parse() reads a file; each element then exposes its tag, text and attributes, while find() and findall() select child elements by name. As in the tree on this page, every value arrives as a string, so 007 keeps its zeros until you convert it. The classic mistake is testing a lookup with if element:. find() returns None when nothing matches, but an element without children can also evaluate as false, so compare with is None.
import xml.etree.ElementTree as ET
xml_text = """<order id="42">
<customer vip="yes">Ava</customer>
<item sku="A1">Mouse</item>
<item sku="B7">Pad</item>
<qty>007</qty>
</order>"""
root = ET.fromstring(xml_text)
print(root.tag, root.attrib) # order {'id': '42'}
customer = root.find("customer")
print(customer.text, customer.get("vip")) # Ava yes
print([(item.get("sku"), item.text) for item in root.findall("item")])
print(root.findtext("qty")) # 007, text is always a string
note = root.find("note") # no such element
print(note is None) # True
Paste your document into the parser above to see its structure before writing the lookups, or generate dataclasses for it with XML to Python.