XML to Crystal Converter Online

Paste any XML and generate Crystal classes with snake_case property declarations and explicit types — String, Int32, Float64, Array(T). Attributes are flagged with comments so wiring up XML.parse is unambiguous, all in your browser.

What is an XML to Crystal converter?

An XML to Crystal converter takes a real XML document and emits Crystal classes whose property declarations mirror the XML element / attribute tree. The OpenFormatter generator inspects every element and attribute, infers Crystal types (String, Int32, Float64, Bool, Array(T)), and produces a class hierarchy ready for the standard-library XML module or the xml_mapping.cr shard.

XML differs from JSON in two ways your Crystal model has to honour. First, XML has attributes on elements (<book id="bk101">) — these are accessed via node["id"] in Crystal, not node.first_element_child. Second, XML allows arbitrary repetition; the generator picks Array(T) for repeated children. Each property carries a comment marking attribute vs element so wiring is unambiguous.

Sample XML and the Crystal class it generates

Input XML

<book id="bk101" lang="en">
  <title>Programming Crystal</title>
  <year>2018</year>
  <price currency="USD">29.99</price>
</book>

Generated Crystal

require "xml"

class Price
  # attribute "currency"
  property currency : String = ""
  # text content
  property text : Float64 = 0.0
end

class Book
  # attribute "id"
  property id : String = ""
  # attribute "lang"
  property lang : String = ""
  # <title>
  property title : String = ""
  # <year>
  property year : Int32 = 0
  # <price>
  property price : Price = Price.new
end

Notice id and lang are flagged as XML attributes, while title and year are child elements. The nested <price> generates its own class with one attribute and one text-content property — exactly what XML.parse exposes.

How to convert XML to Crystal — 4 steps

  1. Paste your XML. A SOAP envelope body, an RSS feed entry, a config file — anything well-formed.
  2. Click Convert. The browser parses the XML and generates Crystal classes for the full element tree.
  3. Review property comments. Confirm attribute markers, switch Int32 to Int64 if needed, change property to getter for read-only fields.
  4. Wire up XML.parse. Copy the classes into your shard and populate them via XML.parse(xml) walking attributes and children.

Statically Typed

Every property carries an explicit Crystal type (String, Int32, Float64, Bool, Array(T)) — the compiler catches mismatches at build time, not runtime.

Attribute vs Element

XML attributes and child elements both become properties, but each carries a comment so your XML.parse wiring uses the right node accessor.

Client-Side Only

Your XML — including SOAP responses with credentials — is parsed in JavaScript on your machine. Verify in DevTools: zero network requests on Convert.

Common use cases

  • check_circleGenerate Crystal classes from a SOAP service response
  • check_circleBuild Crystal models for an RSS or Atom feed reader
  • check_circleConvert configuration XML to typed Crystal classes
  • check_circleGenerate Crystal types from an XSD-described XML file
  • check_circleCreate Crystal unmarshalling models for legacy enterprise XML
  • check_circleBuild typed classes for SAML or WS-Security XML payloads
  • check_circleGenerate Crystal models for sitemap.xml or robots.xml
  • check_circleCreate classes for shard.yml-adjacent XML descriptors

Why client-side conversion matters

SOAP responses and enterprise XML often contain customer PII, API tokens, internal endpoint names, and database identifiers. Pasting them into a server-hosted converter is a compliance violation in most regulated industries. OpenFormatter parses the XML and generates Crystal source entirely in JavaScript on your device — no upload, no logs, no cookies. Open DevTools → Network and confirm no requests fire when you click Convert.

More XML tooling

Validate, format, or convert XML to other languages — every tool runs locally in your browser.

Frequently Asked Questions

How does Crystal handle XML?

Crystal ships with the standard-library XML module — require "xml" and call XML.parse(string) to get an XML::Node. From there you walk children with node.first_element_child, node.children, and access attributes via node["id"]. There is no built-in XML mapping macro analogous to JSON::Serializable; community shards like xml_mapping.cr fill that gap. The generator emits a plain class so you can wire up either approach.

Are Crystal types statically inferred?

Yes. Crystal is statically typed with whole-program inference — every property declaration carries an explicit type (String, Int32, Float64, Bool, or a nested class). The generator picks Int32 for integers and Float64 for decimals; switch to Int64 if your XML carries values outside the 32-bit range.

Why snake_case property names?

Crystal style — like Ruby — favors snake_case for methods, properties, and local variables, reserving CamelCase for class names. The generator converts XML element/attribute names from kebab-case or camelCase into snake_case automatically. If your XML uses snake_case already the names round-trip unchanged.

How are XML attributes distinguished from elements?

Both attributes and child elements become properties on the generated class, but attributes carry a "# attribute" comment above the property declaration. When you populate the class from XML::Node, attributes are accessed with node["id"] while child elements are accessed with node.first_element_child or node.children.find — the comment hints which idiom applies.

How are repeated elements like <tag> represented?

Repeated child elements become an Array(T) property. Crystal arrays are statically typed, so the generator emits Array(Tag) and a default Array(Tag).new initializer — no runtime cast required when you append, and the compiler enforces that every push is the right element type.

Does the output use property or getter / setter?

The generator emits property field : Type — the property macro creates both a reader (foo) and a writer (foo=) in one line, which is the idiomatic Crystal pattern. If you only need a reader, change property to getter; for a writer-only field use setter (rare for XML data classes).

Is the XML I paste sent to your servers?

No. XML is parsed by the browser DOMParser and the Crystal source is generated entirely in JavaScript on your machine. Open DevTools → Network and you will see no requests when you click Convert. Safe for SOAP responses and configuration files containing API keys or credentials.

How do I parse XML into the generated Crystal class?

Use require "xml"; node = XML.parse(xml).first_element_child.not_nil!; book = Book.new; book.id = node["id"]; book.title = node.first_element_child.try(&.content) || ""; — repeated for each field. For repeatable population use the xml_mapping.cr shard which adds a use_xml_mapping macro that wires fields automatically based on a DSL.

XML to Crystal Converter Online — Free