⇄ Code & API Conversion

XML to C# Class Generator (XmlSerializer)

Generate C# classes with XmlSerializer attributes from an XML sample — attributes, repeated elements, namespaces, CDATA and type inference.

XmlSerializer attributes Namespaces Lists & wrappers Type inference

Loading XML → C#…

What this page sends

  • Your input: Processed in this tab and not sent to a server.
  • Share links: Share links put a Base64 copy of your input and output in the URL itself (after #d=). Anyone with the link can read it, so don't share a link that contains secrets.
  • Editor: On desktop screens the code editor (Monaco) is downloaded from cdn.jsdelivr.net; phones get a built-in lightweight editor instead.
  • Page load: Loading the page requests HTML, scripts and images from ByteKiln, fonts from Google Fonts, and sends Google Analytics page views, tool-usage events and catalog interactions (tool/category IDs, result status and whether a click followed search — never your input, output or search terms). Privacy & sharing

How the XML to C# Class Generator (XmlSerializer) Works

Plenty of systems still speak XML: SOAP services, RSS and Atom feeds, bank and government file formats, old web.config sections, vendor exports. On .NET the least painful way to read them is usually XmlSerializer with a set of attributed classes — but writing those classes by hand from a 200-line sample is slow, and it's easy to miss a namespace or an element that repeats only in some records. This generator reads a sample document and builds the classes for you. Every occurrence of every element is examined, not just the first, so repeated elements become List<T>, elements missing from some records become optional, attributes and text content are both captured, and value types are inferred from all the values seen. Namespaces are resolved the way XmlSerializer needs them, wrapper elements like <items><item/></items> become [XmlArray]/[XmlArrayItem] pairs, and class names that would clash with System types such as Guid are renamed. Parse errors are reported with the line and column, like a compiler would.

Parsing

The XML is parsed by a strict, dependency-free XML 1.0 parser that checks matching tags, a single root, quoted and unique attributes and valid entity references, and reports errors with line and column. Namespace prefixes are resolved to URIs. A DOCTYPE is noted but never processed, so no external DTD or entity is ever requested.

Shape inference

Elements are grouped by name and namespace. For each group the tool records every attribute and child element, how many times each child appears in one parent, how many parents contain it, and all text values. Elements that only ever contain text become simple properties; everything else becomes a class.

Type inference

Values are tested as int, long, decimal, bool and ISO 8601 DateTime. Conflicts widen to the smallest type that fits all values, and empty values or leading zeros force string. Optional child elements with value types become nullable (int?, DateTime?).

Attributes

Each property carries the original name in [XmlElement], [XmlAttribute], [XmlArray] or [XmlText], so C# names can be PascalCase while the XML keeps its own casing. An attribute and an element with the same name get distinct property names.

Limitations

  • Classes are inferred from the sample you paste. An element that repeats in other files but appears once here becomes a single property, and optional elements missing from the sample don't exist — use the "treat as a list" option or paste a fuller sample.
  • XSD schemas, DTDs and xsi:type polymorphism are not read; if you have an XSD, xsd.exe or dotnet-xscgen will be more faithful.
  • DOCTYPE declarations aren't supported, and elements with mixed content (text between child elements) can't be represented faithfully by XmlSerializer classes.
  • Output targets XmlSerializer attributes, not DataContractSerializer or LINQ to XML.

FAQ

Short answers for the things developers usually ask before trusting a tool.

Is my XML uploaded?

No. The XML is parsed by a JavaScript parser in your browser and the classes are generated there. Nothing is sent to a server, and DTDs or external entities are never fetched. If you press Share, the link itself carries a readable copy of your input, so don't share links that contain secrets.

How does it decide between a single property and a List<T>?

An element that appears more than once under the same parent becomes a List<T>. A sample with only one item can't prove that, so the tool lists every element that appeared once and lets you tick "treat as a list" for each one.

What happens with elements that have both attributes and text, like <price currency="EUR">9.99</price>?

They become a class with an [XmlAttribute] property for each attribute and an [XmlText] Value property for the text, typed from the values (decimal here).

How are XML namespaces handled?

The root gets [XmlRoot(Namespace = "…")], classes in another namespace get [XmlType(Namespace = "…")], and elements or attributes whose namespace differs from their parent get Namespace = "…" on their attribute, so XmlSerializer reads prefixed documents such as SOAP envelopes and Atom feeds correctly.

How are types inferred?

From every value seen for an element or attribute: whole numbers become int or long, decimals become decimal, true/false become bool, and ISO 8601 dates become DateTime. Mixed values widen (int and decimal become decimal) and anything else is string. Numbers with leading zeros, such as ZIP codes, stay strings. You can turn inference off to make everything a string.

Why are optional attributes not nullable?

XmlSerializer can't serialize Nullable<T> as an attribute. For optional value-type attributes the tool adds a comment explaining the XxxSpecified pattern, which is how XmlSerializer marks an attribute as present or absent.

Related tools

Useful follow-ups when one conversion usually turns into three more.