Tree view, XPath, XSLT, XSD — everything in one tool, like Altova XMLSpy.
{{ ex }}
The CalcSI XML Editor is a free online tool inspired by Altova XMLSpy. You can edit XML documents comfortably in a fully editable tree view or as plain text — with an XPath tester, XSLT transformation, XSD validation, and automatic schema generation built in.
Editing, XPath queries, and XSLT transformations run directly in your browser. For XSD schema validation and automatic schema generation we use the libxml library on our server — fast, standards-compliant, and with no software to install.
Editing, XPath queries, XSLT transformations and JSON/CSV conversion run entirely in your browser — that data never leaves your device. Only for XSD schema validation and automatic schema generation do we send the XML (together with an optional XSD) to our server, where it is processed and immediately discarded — we don't store anything.
XML was published as a W3C Recommendation in 1998 and, despite JSON's dominance, is still standard in many areas: SOAP web services, SEPA/ISO 20022 financial transactions, RSS/Atom feeds, SVG graphics, Office documents (DOCX, ODF), Android layouts, Maven/Gradle configs and EDI exchange. Unlike JSON, XML supports namespaces (xmlns:soap="…"), attributes on elements, mixed content (text + child nodes), comments, CDATA blocks and processing instructions. That expressiveness makes XML more powerful but also more complex.
Three W3C standards accompany XML practically every day: XSD (XML Schema Definition) describes structure, types and constraints (comparable to JSON Schema but older and stricter); XPath (currently 3.1) is a declarative query language for XML nodes, e.g. //book[author='Anna']/title; and XSLT transforms XML into HTML, other XML structures or plain text. This editor provides all three: edit in tree or text view, validate against your XSD, test XPath expressions and run XSLT transformations directly in the browser or via a server helper.
Coming from JSON, three quirks surprise people. First, the prolog — a file should start with a declaration like <?xml version="1.0" encoding="UTF-8"?>. Second, the root element: XML needs exactly one, while JSON allows any number of top-level values. Third, the split between attributes and child nodes: in XML <user id="42">Anna</user>, the ID and the name exist on different "levels" — when converting to JSON this typically appears as {"id":"42","#text":"Anna"} or with a prefix like @_id.
Five concrete workflows cover the most common tasks:
//book[price < 20]/title to list all book titles under 20 EUR. The tester uses the browser's native document.evaluate (XPath 1.0) and returns hits with their path context.Element 'price' is not allowed here), highlighted in the editor.@_, text nodes appear as #text — the standard convention for downstream processing.These typical XML scenarios occur every day:
<?xml version="1.0" encoding="UTF-8"?><root><item id="1">Anna</item></root> — a complete well-formed document with an encoding hint.//book[@category='fiction']/title/text() returns every fiction book's title. The text() function extracts pure text nodes.<user id="42">Anna</user> turns into JSON {"@_id":"42","#text":"Anna"}. On a XML→JSON→XML round trip the builder needs to know which fields used to be attributes.<script><![CDATA[ if (a < b) doStuff(); ]]></script> preserves raw text containing < characters without parsing them as tags — important for SOAP payloads with embedded code.<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">. The prefix soap: references the declared URI; XPath queries must use local-name() or register the namespace.XML has classic foot-guns that hit production regularly. First: XXE (XML External Entity). An attacker injects <!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><foo>&xxe;</foo> — a naively configured parser reads the file and returns it. Best practice: disable DTDs and external entities (libxml2 LIBXML_NONET | LIBXML_NOENT off, Java setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)). Second: Billion laughs / XML bomb. Nested entities (&lol1; → &lol2; → ...) explode a 1 KB document into gigabytes — disabling entity expansion helps here too. Third: namespace hell. SOAP and SAML documents juggle multiple namespaces simultaneously; XPath 1.0 (browser default) requires registered namespace resolvers, otherwise queries return empty. Workaround: local-name() or an XPath 2/3.1 library. Fourth: encoding trap. The XML prolog declares the encoding (encoding="UTF-8"); if that does not match the actual charset, the parse fails with "invalid character". Normalize legacy data with iconv first. Fifth: JSON round trip is not lossless. XML has concepts (mixed content, sibling order, processing instructions) JSON cannot represent. <p>Hello <b>World</b> ok?</p> becomes a creative approximation in JSON.
local-name(): //*[local-name()='Envelope']/*[local-name()='Body']. For SOAP/SAML debugging the local-name() variant is pragmatic because it works without resolver setup.<!DOCTYPE> block. Mitigations: disable DTDs and entities in the parser, never set libxml_disable_entity_loader(false), keep FEATURE_SECURE_PROCESSING active in Java. OWASP lists XXE in its Top 10.xsl:try we recommend Saxon-HE in a build pipeline.@_ prefix for attributes, #text for text. On the way back the builder must follow the same conventions, otherwise attributes wrongly become children.