惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog
Hugging Face - Blog
Hugging Face - Blog
月光博客
月光博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
人人都是产品经理
人人都是产品经理
博客园 - Franky
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
P
Proofpoint News Feed
F
Fortinet All Blogs
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
Jina AI
Jina AI
J
Java Code Geeks
Blog — PlanetScale
Blog — PlanetScale
S
SegmentFault 最新的问题
D
DataBreaches.Net
T
The Blog of Author Tim Ferriss
美团技术团队
博客园 - 司徒正美
宝玉的分享
宝玉的分享
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Apple Machine Learning Research
Apple Machine Learning Research

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
The most-installed XML viewers are 2★ and abandoned. So I...
benjamin · 2026-06-20 · via DEV Community
Cover image for The most-installed XML viewers are 2★ and abandoned. So I hand-wrote one.

benjamin

Open a .xml file in your browser and you usually get one of three things: a wall of unindented text, a viewer that freezes the tab on anything big, or — when the XML is actually broken — a blank page that won't tell you why.

So I went looking for a good XML viewer extension. The most-installed ones on the stores are stuck around 2 stars and haven't been updated since 2023. The reviews rhyme: "doesn't work", "freezes", "just shows plain text". I built Xwift to do the three things those don't.

What it does

  • Tree view — collapsible, syntax-highlighted elements, attributes, text, CDATA, comments and processing instructions. Expand/collapse all.
  • Source view — pretty-print (2 / 4 / tab) or minify, with line numbers and one-click copy.
  • Tells you where it's broken — a tolerant parser that keeps going on malformed input and lists every well-formedness problem with its line:column: mismatched and unclosed tags, duplicate attributes, unbound namespace prefixes, an unescaped &, a stray ]]>… click an error to jump to it.
  • Doesn't choke on big files — parsing runs in a Web Worker, so the tab stays responsive where "load it all into the DOM" viewers stall.

The interesting part (for fellow devs)

The whole thing is hand-written with zero dependencies — no DOMParser, no library. That was the point. The parser is a tolerant single-pass scanner that builds a best-effort tree and collects precise errors, and the formatter re-emits significant whitespace verbatim, so mixed content and xml:space="preserve" survive a round-trip.

Before shipping I ran an adversarial audit over the core, and it surfaced 15 real bugs I would never have caught by eye. A few favorites:

  • Namespace scopes were plain objects, so an unbound prefix literally named toString or __proto__ resolved up the prototype chain and got treated as bound. Fixed with Map-based scopes.
  • The serializer was recursive, so a deeply-nested-but-valid document overflowed the call stack even though the iterative parser handled it fine. Rewrote it as an explicit-stack walk.
  • A [hidden] attribute was silently overridden by a display:flex CSS rule — the empty drop-zone covered the whole viewer. My first E2E missed it because it asserted element content, not visibility.

Then it's verified in real Chrome and real Firefox — the parser produces byte-identical output under V8 and SpiderMonkey.

Respectful by default

  • Zero data collection. Everything runs locally — no network requests with your content, no account, no telemetry. Files you open never leave your browser.
  • Minimal permissions. No host permissions, no <all_urls>, no tab snooping. It reads a page only the moment you ask it to.

Get it

What's the worst XML-viewing moment you've had — the freeze, the blank page, or the "valid" XML that very much wasn't?