XML Editor online

Code

    Export

    My documents

    Click a document to open it. They are stored only in this browser - nothing is uploaded. Clearing the browser's site data removes them, so download the ones you want to keep.

    AI Assistant

    Any AI can write with you - ChatGPT, Claude, Gemini, Copilot.

    1. Click Copy prompt.
    2. Paste it into your AI and say what it should write.
    The AI should

    The document travels in the link after the “#”, which no server sees. What you paste into your AI is handled by its provider.

    Save to your server

    The editor can send each saved version to your own server (a webhook), so your work is kept where you want it. Nothing is sent until you enter an address here.

    What your server receives

    A POST request with JSON (your server must allow CORS from https://xml.giit.ch):

    { "editor": "xml", "event": "save", "id": "…", "name": "Catalog",
      "content": "<?xml version=\"1.0\"?> …",
      "updated": "2026-10-25T09:30:00.000Z" }
    Embed the editor in your website
    <iframe src="https://xml.giit.ch/?embed=1" style="width:100%;height:80vh;border:0"></iframe>
    <script>
    const frame = document.querySelector('iframe');
    addEventListener('message', e => {
      if (e.origin !== 'https://xml.giit.ch' || e.source !== frame.contentWindow) return;
      if (e.data.type === 'xmleditor:ready')
        frame.contentWindow.postMessage({ type: 'xmleditor:load', name: 'Catalog',
          content: '<catalog>…</catalog>' }, 'https://xml.giit.ch');
      if (e.data.type === 'xmleditor:save') saveOnYourServer(e.data.content);
    });
    </script>

    Also possible: ?src=<URL of an XML file> opens a file, &webhook=<URL> saves this document there. The editor can also open in a window of its own (?embed=window), and your page can hand it its own AI prompt and a session key so the AI sends its result to your server (xmleditor:ai, xmleditor:key-request) - see "Use the editor on your own website" below the editor. Details are in llms.txt.

    Help

    How it works

    1. Write XML on the left - or start with New and one of the templates. The tree in the middle shows the elements, attributes, text, comments and CDATA as you type.
    2. Click a node in the tree to go to its place in the code; the cursor in the code shows its node in the tree. Fold elements with the arrow.
    3. Click a name, an attribute value or a text in the tree to edit it right there. Enter or a click elsewhere writes the change into the code (special characters escaped, one step for Undo), Escape cancels. The buttons of a row add a child element or an attribute, move the element up or down, or remove it.
    4. Search marks nodes whose name, value or text contains the words; the XPath field marks the nodes an XPath 1.0 expression selects (_: is the default namespace of the root).
    5. Problems (the first well-formedness error, undeclared namespace prefixes, ids used twice) are listed above the code with line and column - click one to go there.
    6. Node on the right shows the selected node; Insert has ready-made pieces; Convert formats, minifies and turns the document into JSON or YAML.
    7. My documents (the folder button at the top left) lists every document kept in this browser. Export saves XML, minified XML, JSON, YAML or plain text.

    The editor never loads a DTD, a schema or an external entity, and it does not expand entities declared in a DTD: their references stay as written.

    Keyboard shortcuts

    > after a start tag
    Adds the matching end tag
    Ctrl + /
    Comment lines in or out (<!-- -->)
    Ctrl + Enter
    Show the cursor's node in the tree
    Tab / Shift + Tab
    Indent / outdent
    Ctrl + Z / Y
    Undo / redo
    Ctrl + S / E
    Save (download .xml, or to your server) / export
    Ctrl + O
    My documents
    Ctrl + F
    Search in the tree (outside the code)

    Edit XML online, with a live tree

    The XML Editor shows your code and its element tree side by side. Whatever you type appears in the tree right away - elements, attributes, text, comments, CDATA and namespaces - and a click on any node takes you to its place in the code. You can also edit names, values and text right in the tree, run XPath queries and convert the document to JSON or YAML.

    Everything runs in your browser. Documents are not uploaded, there is no sign-up and no advertising.

    What the editor can do

    Code with highlighting

    Tags, attributes, values, entities, comments and CDATA in their own colors, line numbers, end tags that close by themselves and a clear list of problems with line and column.

    The element tree

    Fold and unfold elements, see attributes, text, comments, processing instructions and namespaces, and follow the path of the selected node.

    Edit in the tree

    Rename elements and attributes, change values and text, add, move and remove elements - written into the code as small edits, with special characters escaped.

    XPath and search

    An XPath 1.0 field marks the matching nodes; the search finds names, values and text. Namespace prefixes of the document work in XPath.

    Safe with any file

    No DTD, schema or external entity is ever loaded and no entity is expanded, so XXE and entity bombs do not work.

    Format and convert

    Indent or minify the document, or turn it into JSON or YAML: attributes as @name, text as #text, repeated elements as lists.

    How it works

    1. Start - choose a template under "New", open an .xml file or paste XML code.
    2. Edit - type in the code or click values in the tree; the problems above the code tell you what is not well-formed.
    3. Export - save the XML, a minified copy, JSON, YAML or the plain text.

    Use the editor on your own website

    Any https page (and localhost) can embed the editor with an <iframe> and ?embed=1 - no sign-up, no key. Embedded, the editor hides this text and shows a Save button. There are two ways to get the document in and out.

    1. Open a file from a link, save to your server

    src= opens a file (your server must allow CORS), webhook= makes "Save" (Ctrl+S) send the document to that address. Add &token=… for an Authorization: Bearer … header and &auto to save after every change.

    <iframe src="https://xml.giit.ch/?embed=1&src=https://your-site.com/data/catalog.xml&webhook=https://your-site.com/save.php"
            allow="clipboard-write" style="width:100%;height:800px;border:0"></iframe>

    The webhook gets a POST with JSON { editor: "xml", event: "save", id, name, content, updated }. A small PHP script that stores it:

    <?php
    header('Access-Control-Allow-Origin: https://xml.giit.ch');
    header('Access-Control-Allow-Headers: Content-Type, Authorization');
    header('Access-Control-Allow-Methods: POST, OPTIONS');
    if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') exit;
    if (($_SERVER['HTTP_AUTHORIZATION'] ?? '') !== 'Bearer SECRET') { http_response_code(403); exit; }
    $d = json_decode(file_get_contents('php://input'), true);
    $name = preg_replace('/[^\w\- ]/u', '_', $d['name']);
    file_put_contents(__DIR__ . "/data/$name.xml", $d['content']);
    echo '{"ok":true}';

    2. Your page holds the document (postMessage)

    The editor says xmleditor:ready, your page answers with xmleditor:load, the editor reports xmleditor:loaded, xmleditor:change on real edits and xmleditor:save when the user saves. Your page may send xmleditor:get (the current state) or xmleditor:save (press Save). Saving then goes through your own login and session.

    <iframe id="ed" src="https://xml.giit.ch/?embed=1" allow="clipboard-write" style="width:100%;height:800px;border:0"></iframe>
    <script>
    const ed = document.getElementById('ed');
    const ORIGIN = 'https://xml.giit.ch';
    
    addEventListener('message', async e => {
      if (e.source !== ed.contentWindow || e.origin !== ORIGIN) return;
      const m = e.data;
      if (m.type === 'xmleditor:ready') {               // the editor is ready: hand it the document
        ed.contentWindow.postMessage({
          type: 'xmleditor:load',
          name: 'Catalog',
          content: await (await fetch('/data/catalog.xml')).text()
        }, ORIGIN);
      }
      if (m.type === 'xmleditor:change') document.title = '● not saved';     // a real edit
      if (m.type === 'xmleditor:save') {                // the user clicked "Save"
        await fetch('/api/save', { method: 'POST', headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ name: m.name, content: m.content }) });
        document.title = 'Saved';
      }
    });
    
    // A save button on your own page: the answer comes as xmleditor:save
    function saveNow() { ed.contentWindow.postMessage({ type: 'xmleditor:get' }, ORIGIN); }
    </script>

    AI Assistant inside your page: it works in the frame too. With allow="clipboard-write" on the iframe, "Copy prompt" uses the clipboard directly (otherwise the editor falls back to the old copy command, or shows the prompt to copy by hand). A link the AI sends cannot reach an editor inside another website, so the editor tells the AI and the user to paste the AI's whole answer into the editor instead - or open the editor in a window of its own.

    3. In a window of its own

    window.open("https://xml.giit.ch/?embed=window", "xmleditor-17") opens the full editor in its own window and speaks the same messages with window.opener. Links from an AI reach it there. xmleditor:load may also carry context: { host, title, rules } - the AI prompt then says where the document belongs and follows your rules - and hook: { url, token }, a webhook for this document only that is never stored. Closing the window with unsaved changes sends xmleditor:closing.

    4. AI through your own server

    Hand the editor your own prompt, an address on your site and a key for this editor session. The AI dialog then shows "Connected to" your site, what you tell the AI, and the choice change the current document or make a new one; Copy prompt puts it all together. The AI posts its result with the key to your server, and your page opens it in the editor - a new document opens separately and stays in the user's browser. One key per editor session: it stays valid while the editor is open, and only while it has none the editor asks for it with xmleditor:key-request. The editor never sends the key itself and never stores it; the address must be https on your own host or a subdomain of it.

    const key = async () => (await fetch('/api/ai-key.php?doc=17')).json();   // one key per editor session
    const k = await key();
    ed.contentWindow.postMessage({ type: 'xmleditor:load', name: 'Catalog', content, ai: {
      label: 'My Site', prompt: 'Keep the sku attributes. Prices in CHF.',
      endpoint: 'https://your-site.com/api/ai-result.php', key: k.key } }, ORIGIN);
    // remember the id from xmleditor:loaded and ignore change/save/closing with another id
    // only while the editor has no key:
    if (m.type === 'xmleditor:key-request') { const k = await key(); ed.contentWindow.postMessage({ type: 'xmleditor:ai', key: k.key }, ORIGIN); }
    // while the editor is open, tell your server every minute; closing the editor or the page voids the key
    setInterval(() => fetch('/api/ai-key.php?alive=' + k.key.slice(0, 8)), 60000);
    // your server has a result (polling, SSE …): target is "current" or "new"
    ed.contentWindow.postMessage({ type: 'xmleditor:load', name: 'Catalog', content: draft, from: 'ai', target }, ORIGIN);

    Make keys with at least 128 random bits, store only their hash, bind each to the logged-in user, the document and this editor session, make one per session, keep it valid only while your page reports the session as open, and void it when the editor or the page closes.

    The whole protocol is in llms.txt - give it to an AI and it builds the connection for your system. The LaTeX Editor and the SVG Editor work the same way with the prefixes latexeditor: and svgeditor:.

    Frequently asked questions

    Is my XML uploaded?

    No. The editor runs entirely in your browser. Your documents are never sent to a server, unless you set up a webhook to your own server yourself.

    Does the editor check my XML?

    Yes. It uses the browser's own XML parser and shows the first well-formedness error with its line and column, plus undeclared namespace prefixes and ids that are used twice. It does not validate against a DTD or an XML Schema.

    Is it safe to open XML with a DTD or external entities?

    Yes. The editor never loads a DTD, a schema or an external entity and never expands entities from a DTD, so XXE and entity expansion attacks do not work. References to such entities stay in the text as they are written.

    How do I use XPath?

    Type an XPath 1.0 expression above the tree, for example //book[price > 30]/title. The matching nodes are marked in the tree; the arrows go from one to the next. Prefixes declared in the document work, and _: stands for the default namespace of the root element.

    Can I convert XML to JSON or YAML?

    Yes. Under Convert or Export, the document becomes JSON or YAML: attributes as @name, text as #text, repeated elements as lists.

    Where are my documents saved?

    Only in your browser. Click the folder button at the top left (My documents) to open, rename, duplicate, download or delete them. Clearing your browser's site data removes them, so download the ones you want to keep - or let the editor send them to your own server ("Save to server").

    Can an AI write in the XML Editor?

    Yes, any AI - ChatGPT, Claude, Gemini, Copilot or the AI in your coding tool. Click "AI Assistant", then "Copy prompt", paste it into your AI and say what it should write. The AI answers with a link; click it and the document appears in your editor. "Undo" takes every change back.

    Can I use the editor on my own website?

    Yes. Embed it with an iframe and exchange documents with postMessage, or let it send every saved version to your server with a webhook. See Use the editor on your own website for examples.

    Does the XML Editor cost anything?

    No. The editor is free, without ads and without sign-up.