PackageTrack
Sign in Get early access

quick-xml

High performance xml reader and writer

0.42.0 380M downloads/mo #300 most downloaded on crates.io tafia/quick-xml

What this package is like to depend on

Last release today

22 Aug 2026

Ships fairly regularly

a new release about every 6 weeks

Nearly every release is documented

notes for 94 of 97 stable releases

4 versions withdrawn

withdrawn after publishing

11 years old

104 releases · first in 2016

10 releases in the last 12 months

see the full history below

Release timeline

104 releases · Feb 2016 to Aug 2026
2017 2018 2019 2020 2021 2022 2023 2024 2025 2026
Release Pre-release Withdrawn

Releases

latest 60 of 104
  1. 0.42.0 22 Aug 2026
    Release notes

    What's Changed

    0.42.0 -- 2026-08-22

    This is a large release. The primary change is an ergonomic improvement across the entire API -
    quick_xml now makes use of &str and String types where possible instead of
    &[u8] and Vec<u8>. This requires significant refactoring of downstream code,
    but should result in a net simplification as well as potential performance improvements,
    and opens up additional opportunities in future releases.

    The MSRV has been raised to 1.86. We now use Rust 2024 Edition.

    Breaking Changes

    • #963: Reader now validates that input is valid UTF-8 when constructing events.
      Non-UTF-8 input passed to Reader::from_reader() without DecodingReader will now
      produce Error::Encoding instead of silently passing through invalid bytes.
      Use DecodingReader to transcode non-UTF-8 sources.
    • #963: Name types (QName, LocalName, Prefix, Namespace, PrefixDeclaration)
      now wrap &str instead of &[u8]. into_inner() returns &str, and AsRef<str>
      is implemented (AsRef<[u8]> has been removed). ResolveResult::Unknown now contains String
      instead of Vec<u8>, and NamespaceError variants contain String instead of Vec<u8>.
    • #963: Removed the decoder: Decoder field from event types (BytesStart, BytesText,
      BytesCData, BytesRef) and Attributes. The decoder() method is no longer available
      on these types. Decode methods on events now always assume UTF-8 input.
      Error::missed_end() no longer takes a Decoder parameter.
    • #963: Event types (BytesStart, BytesEnd, BytesText, BytesCData, BytesPI,
      BytesRef) now store Cow<str> internally instead of Cow<[u8]>. into_inner() on
      BytesText, BytesCData, BytesPI, and BytesRef now returns Cow<str>.
      BytesStart::set_name() now takes &str instead of &[u8].
    • #963: All event types and the Event enum now implement Deref<Target = str>
      instead of Deref<Target = [u8]>. Explicit AsRef<str> impls are provided to
      avoid ambiguity.
    • #963: Removed decode() methods from BytesText, BytesCData, and BytesRef.
      Content is already available as &str via Deref. The xml10_content(),
      xml11_content(), xml_content(), and html_content() methods now return
      Cow<str> directly instead of Result<Cow<str>, EncodingError>.
    • #963: Attribute::value is now Cow<'a, str> instead of Cow<'a, [u8]>.
      The From<(&[u8], &[u8])> impl has been removed.
    • #963: BytesDecl::version(), encoding(), and standalone() now return
      Cow<'_, str> instead of Cow<'_, [u8]>.
    • #963: Removed Reader::decoder() method. Use Reader::encoding() instead
      (available with the encoding feature). Removed decoder() from the XmlRead
      serde trait. Removed all methods from Decoder (the struct is kept only for
      backward compatibility with deprecated Attribute methods).
    • #980: NamespaceError::TooManyDeclarations has been renamed to TooManyBindings,
      and NamespaceResolver::set_max_declarations_per_element has been renamed to
      NamespaceResolver::set_max_namespace_bindings, and the semantic behavior has
      changed slightly. The default maximum has also been reduced from 256 to 128.
    • #1000: DeError::UnexpectedStart renamed to DeError::MixedContent. That error
      is emitted when you try to deserialize boolean, number or string field from
      something like <field>text <tag/> another text</field>.

    Bug Fixes

    • #670: Serde serializer now escapes \r, \n, and \t in attribute values
      as &#13;, &#10;, and &#9; respectively, preventing silent data loss from
      XML attribute-value normalization on round-trip. Likewise Attribute::from
      performs the same transformation.
    • #953: The serde Deserializer now correctly handles namespaces. Previously
      the namespace bindings might be applied or removed before the event actually
      was consumed which lead to a couple of bugs.
    • #989: Attributes::new and Attributes::html now return empty iterators when
      their starting position is past the end of the input instead of panicking.
    • #977: NamespaceResolver::push (and hence every NsReader Start/Empty
      event) now returns the new NamespaceError::TooDeeplyNested when a document
      nests elements deeper than u16::MAX, instead of overflowing the internal
      u16 depth counter. Previously the unguarded nesting_level += 1 panicked
      under overflow-checks builds and silently wrapped in release, corrupting
      namespace-scope bookkeeping on deeply nested untrusted input.
    • #980: NamespaceResolver now caps the total number of in-scope namespace
      bindings (default 128, configurable via set_max_namespace_bindings),
      replacing the previous per-element max_declarations_per_element limit.
    • #978: The serde Deserializer now enforces a configurable recursion-depth
      limit (default 128, matching serde_json). Deeply nested XML returns
      DeError::TooDeeplyNested instead of overflowing the native call stack.
      Use Deserializer::recursion_limit() to adjust.
    • #990: \r in text content is now escaped as &#13; by the serde serializer,
      BytesText::new(), escape(), partial_escape(), and minimal_escape(),
      preventing silent conversion to \n from XML end-of-line normalization on
      round-trip. Note that \r cannot be preserved through CDATA serialization
      because character references are not permitted inside CDATA sections.

    Misc Changes

    • #269: Added getting-started examples (getting_started, writer,
      serde_roundtrip, reader_patterns, visitor) and an examples/README.md
      guide on choosing between the serde and pull-reader/writer APIs.
    • #331: Documentation about lifetimes of the events and attributes has been clarified.
    • #859: Added an example showing how to pretty-print serialized XML.
    • #983: Adopted an AI use and contribution policy for new upstream contributions.
    • #963: MSRV bumped to 1.86 (April 2025)
    • #963: Deprecated Attribute methods that take a Decoder parameter, since
      attribute values are now always valid UTF-8: decoded_and_normalized_value(),
      decoded_and_normalized_value_with(), decode_and_unescape_value(), and
      decode_and_unescape_value_with(). Use normalized_value() and
      normalized_value_with() instead.
    • #1002: Added NamespaceResolver::with that allows temporary applying namespace
      bindings from the start tag for the scope of a provided closure F, without making any
      persistent change to the resolver. It is useful to check a peeked event which is
      not yet consumed in custom implementations of peekable reader.
    • #1002: Added Deserializer::resolver and Deserializer::resolver_mut methods
      to get a namespace resolver used by this deserializer, because it no longer uses
      an NsReader internally.
    • #1005: Implement Hash, PartialOrd, and Ord for BytesText and BytesCData types.

    New Contributors

    Full Changelog: v0.41.0...v0.42.0

    Open source →
    Release notes

    This is a large release. The primary change is an ergonomic improvement across the entire API - quick_xml now makes use of &str and String types where possible instead of &[u8] and Vec<u8>. This requires significant refactoring of downstream code, but should result in a net simplification as well as potential performance improvements, and opens up additional opportunities in future releases.

    The MSRV has been raised to 1.86. We now use Rust 2024 Edition.

    Breaking Changes

    • #963: Reader now validates that input is valid UTF-8 when constructing events. Non-UTF-8 input passed to Reader::from_reader() without DecodingReader will now produce Error::Encoding instead of silently passing through invalid bytes. Use DecodingReader to transcode non-UTF-8 sources.
    • #963: Name types (QName, LocalName, Prefix, Namespace, PrefixDeclaration) now wrap &str instead of &[u8]. into_inner() returns &str, and AsRef<str> is implemented (AsRef<[u8]> has been removed). ResolveResult::Unknown now contains String instead of Vec<u8>, and NamespaceError variants contain String instead of Vec<u8>.
    • #963: Removed the decoder: Decoder field from event types (BytesStart, BytesText, BytesCData, BytesRef) and Attributes. The decoder() method is no longer available on these types. Decode methods on events now always assume UTF-8 input. Error::missed_end() no longer takes a Decoder parameter.
    • #963: Event types (BytesStart, BytesEnd, BytesText, BytesCData, BytesPI, BytesRef) now store Cow<str> internally instead of Cow<[u8]>. into_inner() on BytesText, BytesCData, BytesPI, and BytesRef now returns Cow<str>. BytesStart::set_name() now takes &str instead of &[u8].
    • #963: All event types and the Event enum now implement Deref<Target = str> instead of Deref<Target = [u8]>. Explicit AsRef<str> impls are provided to avoid ambiguity.
    • #963: Removed decode() methods from BytesText, BytesCData, and BytesRef. Content is already available as &str via Deref. The xml10_content(), xml11_content(), xml_content(), and html_content() methods now return Cow<str> directly instead of Result<Cow<str>, EncodingError>.
    • #963: Attribute::value is now Cow<'a, str> instead of Cow<'a, [u8]>. The From<(&[u8], &[u8])> impl has been removed.
    • #963: BytesDecl::version(), encoding(), and standalone() now return Cow<'_, str> instead of Cow<'_, [u8]>.
    • #963: Removed Reader::decoder() method. Use Reader::encoding() instead (available with the encoding feature). Removed decoder() from the XmlRead serde trait. Removed all methods from Decoder (the struct is kept only for backward compatibility with deprecated Attribute methods).
    • #980: NamespaceError::TooManyDeclarations has been renamed to TooManyBindings, and NamespaceResolver::set_max_declarations_per_element has been renamed to NamespaceResolver::set_max_namespace_bindings, and the semantic behavior has changed slightly. The default maximum has also been reduced from 256 to 128.
    • #1000: DeError::UnexpectedStart renamed to DeError::MixedContent. That error is emitted when you try to deserialize boolean, number or string field from something like <field>text <tag/> another text</field>.

    Bug Fixes

    • #670: Serde serializer now escapes \r, \n, and \t in attribute values as &#13;, &#10;, and &#9; respectively, preventing silent data loss from XML attribute-value normalization on round-trip. Likewise Attribute::from performs the same transformation.
    • #953: The serde Deserializer now correctly handles namespaces. Previously the namespace bindings might be applied or removed before the event actually was consumed which lead to a couple of bugs.
    • #989: Attributes::new and Attributes::html now return empty iterators when their starting position is past the end of the input instead of panicking.
    • #977: NamespaceResolver::push (and hence every NsReader Start/Empty event) now returns the new NamespaceError::TooDeeplyNested when a document nests elements deeper than u16::MAX, instead of overflowing the internal u16 depth counter. Previously the unguarded nesting_level += 1 panicked under overflow-checks builds and silently wrapped in release, corrupting namespace-scope bookkeeping on deeply nested untrusted input.
    • #980: NamespaceResolver now caps the total number of in-scope namespace bindings (default 128, configurable via set_max_namespace_bindings), replacing the previous per-element max_declarations_per_element limit.
    • #978: The serde Deserializer now enforces a configurable recursion-depth limit (default 128, matching serde_json). Deeply nested XML returns DeError::TooDeeplyNested instead of overflowing the native call stack. Use Deserializer::recursion_limit() to adjust.
    • #990: \r in text content is now escaped as &#13; by the serde serializer, BytesText::new(), escape(), partial_escape(), and minimal_escape(), preventing silent conversion to \n from XML end-of-line normalization on round-trip. Note that \r cannot be preserved through CDATA serialization because character references are not permitted inside CDATA sections.

    Misc Changes

    • #269: Added getting-started examples (getting_started, writer, serde_roundtrip, reader_patterns, visitor) and an examples/README.md guide on choosing between the serde and pull-reader/writer APIs.
    • #331: Documentation about lifetimes of the events and attributes has been clarified.
    • #859: Added an example showing how to pretty-print serialized XML.
    • #983: Adopted an AI use and contribution policy for new upstream contributions.
    • #963: MSRV bumped to 1.86 (April 2025)
    • #963: Deprecated Attribute methods that take a Decoder parameter, since attribute values are now always valid UTF-8: decoded_and_normalized_value(), decoded_and_normalized_value_with(), decode_and_unescape_value(), and decode_and_unescape_value_with(). Use normalized_value() and normalized_value_with() instead.
    • #1002: Added NamespaceResolver::with that allows temporary applying namespace bindings from the start tag for the scope of a provided closure F, without making any persistent change to the resolver. It is useful to check a peeked event which is not yet consumed in custom implementations of peekable reader.
    • #1002: Added Deserializer::resolver and Deserializer::resolver_mut methods to get a namespace resolver used by this deserializer, because it no longer uses an NsReader internally.
    • #1005: Implement Hash, PartialOrd, and Ord across all Bytes* types.
    Open source →
  2. 0.41.0 29 Jun 2026
    Release notes

    What's Changed

    New Features

    • #970: Add NsReader::resolver_mut() and NamespaceResolver::{max_declarations_per_element, set_max_declarations_per_element}.

    Bug Fixes

    • #969: Attributes (and anything that iterates BytesStart::attributes() with the default with_checks(true)) no longer takes O(N²) time on a start tag with a large number of attributes. Small tags keep the previous linear scan; larger ones switch to a 64-bit hash pre-filter, so the whole tag is O(N). The exact AttrError::Duplicated(new, prev) positions are unchanged.
    • #970: NamespaceResolver::push (and hence every NsReader Start/Empty event) now rejects a start tag that declares more than DEFAULT_MAX_DECLARATIONS_PER_ELEMENT (256) xmlns / xmlns:* namespace bindings, returning the new NamespaceError::TooManyDeclarations. Previously push allocated one NamespaceBinding per declaration with no upper bound, before the event was returned to the caller, so an NsReader consumer could not bound its memory exposure on untrusted input. The limit is configurable via NamespaceResolver::set_max_declarations_per_element (use usize::MAX to disable).

    New Contributors

    Full Changelog: v0.40.1...v0.41.0

    Open source →
    Release notes

    New Features

    • #970: Add NsReader::resolver_mut() and NamespaceResolver::{max_declarations_per_element, set_max_declarations_per_element}.

    Bug Fixes

    • #969: Attributes (and anything that iterates BytesStart::attributes() with the default with_checks(true)) no longer takes O(N²) time on a start tag with a large number of attributes. Small tags keep the previous linear scan; larger ones switch to a 64-bit hash pre-filter, so the whole tag is O(N). The exact AttrError::Duplicated(new, prev) positions are unchanged.
    • #970: NamespaceResolver::push (and hence every NsReader Start/Empty event) now rejects a start tag that declares more than 256 xmlns / xmlns:* namespace bindings, returning the new NamespaceError::TooManyDeclarations. Previously push allocated one NamespaceBinding per declaration with no upper bound, before the event was returned to the caller, so an NsReader consumer could not bound its memory exposure on untrusted input. The limit is configurable via NamespaceResolver::set_max_declarations_per_element (use usize::MAX to disable).
    Open source →
  3. 0.40.1 15 May 2026
    Release notes

    What's Changed

    • #964: Fix unreachable!() panic in the serde deserializer when a DOCTYPE declaration appears between two text runs inside an element (e.g. <a>x<!DOCTYPE y>z</a>). The DOCTYPE used to break drain_text's consecutive-text merge, so two DeEvent::Text events reached read_text and tripped its "Cannot be two consequent Text events" invariant. DOCTYPE is now treated as transparent during text drain — it still goes through the entity resolver, but the surrounding text is merged into one run. Discovered via libFuzzer on a real-world SAML deserializer harness.

    New Contributors

    Full Changelog: v0.40.0...v0.40.1

    Open source →
    Release notes

    Bug Fixes

    • #964: Fix unreachable!() panic in the serde deserializer when a DOCTYPE declaration appears between two text runs inside an element (e.g. <a>x<!DOCTYPE y>z</a>). The DOCTYPE used to break drain_text's consecutive-text merge, so two DeEvent::Text events reached read_text and tripped its "Cannot be two consequent Text events" invariant. DOCTYPE is now treated as transparent during text drain — it still goes through the entity resolver, but the surrounding text is merged into one run. Discovered via libFuzzer on a real-world SAML deserializer harness.
    Open source →
  4. 0.40.0 11 May 2026
    Release notes

    What's Changed

    MSRV bumped to 1.79.

    Now quick-xml supports the UTF-16 and ISO-2022-JP encoded documents. See the new DecodingReader type.

    New Features

    • #956: Add DecodingReader, a BufRead adapter that auto-detects encoding from BOM or XML declaration and transcodes to UTF-8. Enabled by the encoding feature.

    • #938: Add new enumeration XmlVersion and typified getter BytesDecl::xml_version().

    • #938: Add new error variant IllFormedError::UnknownVersion.

    • #371: Add new error variant EscapeError::TooManyNestedEntities.

    • #371: Improved compliance with the XML attribute value normalization process by adding

      • Attribute::normalized_value()
      • Attribute::normalized_value_with()
      • Attribute::decoded_and_normalized_value()
      • Attribute::decoded_and_normalized_value_with()

      which ought to be used in place of deprecated

      • Attribute::unescape_value()
      • Attribute::unescape_value_with()
      • Attribute::decode_and_unescape_value()
      • Attribute::decode_and_unescape_value_with()

      Deprecated functions now behaves the same as newly added.

    Bug Fixes

    • #938: Use correct rules for EOL normalization in Deserializer when parse XML 1.0 documents. Previously XML 1.1. rules was applied.

    Misc Changes

    • #914: Remove deprecated .prefixes(), .resolve(), .resolve_attribute(), and .resolve_element() of NsReader. Use .resolver().<...> methods instead.
    • #938: Now BytesText::xml_content, BytesCData::xml_content and BytesRef::xml_content accepts XmlVersion parameter to apply correct EOL normalization rules.
    • #944: read_text() now returns BytesText which allows you to get the content with properly normalized EOLs. To get the previous behavior use .read_text().decode()?.
    • #956: Bumped MSRV from 1.59 (Feb 2022) to 1.79 (June 2024)

    New Contributors

    Full Changelog: v0.39.4...v0.40.0

    Open source →
    Release notes

    MSRV bumped to 1.79.

    Now quick-xml supports UTF-16 encoded documents. See the new DecodingReader type.

    New Features

    • #956: Add DecodingReader, a BufRead adapter that auto-detects encoding from BOM or XML declaration and transcodes to UTF-8. Enabled by the encoding feature.

    • #938: Add new enumeration XmlVersion and typified getter BytesDecl::xml_version().

    • #938: Add new error variant IllFormedError::UnknownVersion.

    • #371: Add new error variant EscapeError::TooManyNestedEntities.

    • #371: Improved compliance with the XML attribute value normalization process by adding

      • Attribute::normalized_value()
      • Attribute::normalized_value_with()
      • Attribute::decoded_and_normalized_value()
      • Attribute::decoded_and_normalized_value_with()

      which ought to be used in place of deprecated

      • Attribute::unescape_value()
      • Attribute::unescape_value_with()
      • Attribute::decode_and_unescape_value()
      • Attribute::decode_and_unescape_value_with()

      Deprecated functions now behaves the same as newly added.

    Bug Fixes

    • #938: Use correct rules for EOL normalization in Deserializer when parse XML 1.0 documents. Previously XML 1.1. rules was applied.

    Misc Changes

    • #914: Remove deprecated .prefixes(), .resolve(), .resolve_attribute(), and .resolve_element() of NsReader. Use .resolver().<...> methods instead.
    • #938: Now BytesText::xml_content, BytesCData::xml_content and BytesRef::xml_content accepts XmlVersion parameter to apply correct EOL normalization rules.
    • #944: read_text() now returns BytesText which allows you to get the content with properly normalized EOLs. To get the previous behavior use .read_text().decode()?.
    • #956: Bumped MSRV from 1.59 (Feb 2022) to 1.79 (June 2024)
    Open source →
  5. 0.39.4 08 May 2026
    Release notes

    Bug Fixes

    • #957: Fix slice-index panic when reading malformed DTD whose unknown markup is split across BufReader chunks. As with #950, the returned Event::DocType may contain the malformed DTD; this fix only ensures that the parser does not panic.
    • #960: Fix sibling slice-index panic when a single chunk delivers < followed by 9+ bytes of unknown markup inside a DTD internal subset. Same disposition as #957 / #950: parser must not panic; DTD validity reporting is a future improvement.

    Full Changelog: v0.39.3...v0.39.4

    Open source →
    Release notes

    Bug Fixes

    • #957: Fix slice-index panic when reading malformed DTD whose unknown markup is split across BufReader chunks. As with #950, the returned Event::DocType may contain the malformed DTD; this fix only ensures that the parser does not panic.
    • #960: Fix sibling slice-index panic when a single chunk delivers < followed by 9+ bytes of unknown markup inside a DTD internal subset. Same disposition as #957 / #950: parser must not panic; DTD validity reporting is a future improvement.
    Open source →
  6. 0.39.3 04 May 2026
    Release notes

    Bug Fixes

    • #950: Fix subtraction with overflow when parse malformed DTD in some cases. Note, that currently we do not check the validity of DTD, so the returned Event::DocType may contain the malformed DTD.

    Full Changelog: v0.39.2...v0.39.3

    Open source →
    Release notes

    Bug Fixes

    • #950: Fix subtraction with overflow when parse malformed DTD in some cases. Note, that currently we do not check the validity of DTD, so the returned Event::DocType may contain the malformed DTD.
    Open source →
  7. 0.39.2 20 Feb 2026
    Release notes

    What's Changed

    New Features

    • #483: Implement read_text_into() and read_text_into_async().

    Bug Fixes

    • #939: Fix parsing error of the tag from buffered reader, when the first byte < is the last in the BufRead internal buffer. This is the regression from #936.

    Full Changelog: v0.39.1...v0.39.2

    Open source →
    Release notes

    New Features

    • #483: Implement read_text_into() and read_text_into_async().

    Bug Fixes

    • #939: Fix parsing error of the tag from buffered reader, when the first byte < is the last in the BufRead internal buffer. This is the regression from #936.
    Open source →
  8. 0.39.1 15 Feb 2026
    Release notes

    New Features

    • #598: Add method NamespaceResolver::set_level which may be helpful in some circumstances.

    Bug Fixes

    • #597: Fix incorrect processing of namespace scopes in NsReader::read_to_end NsReader::read_to_end_into, NsReader::read_to_end_into_async and NsReader::read_text. The scope started by a start element was not ended after that call.
    • #936: Fix incorrect result of .read_text() when it is called after reading Text or GeneralRef event.
    Open source →
  9. 0.39.0 11 Jan 2026
    Release notes

    What's Changed

    Added a way to configure Writer. Now all configuration is contained in the writer::Config
    struct and can be applied at once. When serde-types feature is enabled, configuration is serializable.

    New Features

    • #846: Add methods config() and config_mut() to inspect and change the writer configuration.
    • #846: Add ability to write space before /> in self-closed tags for maximum compatibility with XHTML.
    • #846: Add method empty_element_handling() as a more powerful alternative to expand_empty_elements() in Serializer.
    • #929: Allow to pass list of field names to impl_deserialize_for_internally_tagged_enum! macro which is required if you enum variants contains $value fields.

    Bug Fixes

    • #923: Implement correct skipping of well-formed DTD.

    Misc Changes

    • #908: Increase minimal supported serde version from 1.0.139 to 1.0.180.
    • #913: Deprecate .prefixes(), .resolve(), .resolve_attribute(), and .resolve_element() of NsReader. Use .resolver().bindings() and .resolver().resolve() methods instead.
    • #913: Attributes::has_nil now accepts NamespaceResolver instead of Reader<R>.
    • #924: (breaking change) Split SyntaxError::UnclosedPIOrXmlDecl into UnclosedPI and UnclosedXmlDecl for more precise error reporting.
    • #924: (breaking change) Parser::eof_error now takes &self and content &[u8] parameters.
    • #926: (breaking change) Split SyntaxError::UnclosedTag into UnclosedTag,
      UnclosedSingleQuotedAttributeValue and UnclosedDoubleQuotedAttributeValue for more precise error reporting.

    New Contributors

    Full Changelog: v0.38.4...v0.39.0

    Open source →
    Release notes

    Added a way to configure Writer. Now all configuration is contained in the writer::Config struct and can be applied at once. When serde-types feature is enabled, configuration is serializable.

    New Features

    • #846: Add methods config() and config_mut() to inspect and change the writer configuration.
    • #846: Add ability to write space before /> in self-closed tags for maximum compatibility with XHTML.
    • #846: Add method empty_element_handling() as a more powerful alternative to expand_empty_elements() in Serializer.
    • #929: Allow to pass list of field names to impl_deserialize_for_internally_tagged_enum! macro which is required if you enum variants contains $value fields.

    Bug Fixes

    • #923: Implement correct skipping of well-formed DTD.

    Misc Changes

    • #908: Increase minimal supported serde version from 1.0.139 to 1.0.180.
    • #913: Deprecate .prefixes(), .resolve(), .resolve_attribute(), and .resolve_element() of NsReader. Use .resolver().bindings() and .resolver().resolve() methods instead.
    • #913: Attributes::has_nil now accepts NamespaceResolver instead of Reader<R>.
    • #924: (breaking change) Split SyntaxError::UnclosedPIOrXmlDecl into UnclosedPI and UnclosedXmlDecl for more precise error reporting.
    • #924: (breaking change) Parser::eof_error now takes &self and content &[u8] parameters.
    • #926: (breaking change) Split SyntaxError::UnclosedTag into UnclosedTag, UnclosedSingleQuotedAttributeValue and UnclosedDoubleQuotedAttributeValue for more precise error reporting.
    Open source →
  10. 0.38.4 11 Nov 2025
    Release notes

    What's Changed

    New Features

    • #353: Add ability to serialize textual content as CDATA sections in Serializer. Everywhere where the text node may be created, a CDATA section(s) could be produced instead. See the new Serializer::text_format() method.

    Bug Fixes

    • #912: Fix deserialization of numbers, booleans and characters that is space-wrapped, for example <int> 42 </int>. That space characters are usually indent added during serialization and other XML serialization libraries trims them

    Misc Changes

    • #901: Fix running tests on 32-bit architecture
    • #909: Avoid some allocations in the Serializer

    New Contributors

    Full Changelog: v0.38.3...v0.38.4

    Open source →
    Release notes

    New Features

    • #353: Add ability to serialize textual content as CDATA sections in Serializer. Everywhere where the text node may be created, a CDATA section(s) could be produced instead. See the new Serializer::text_format() method.

    Bug Fixes

    • #912: Fix deserialization of numbers, booleans and characters that is space-wrapped, for example <int> 42 </int>. That space characters are usually indent added during serialization and other XML serialization libraries trims them

    Misc Changes

    • #901: Fix running tests on 32-bit architecture
    • #909: Avoid some allocations in the Serializer
    Open source →
  11. 0.38.3 24 Aug 2025
    Release notes

    Bug Fixes

    • #895: Fix incorrect normalization of \rX EOL sequences where X is a char which is UTF-8 encoded as [c2 xx], except [c2 85].

    Misc Changes

    • #895: Add new xml10_content() and xml11_content() methods which behaves the same as html_content() and xml_content() methods, but express intention more clearly.
    Open source →
  12. 0.38.2 19 Aug 2025
    Release notes

    New Features

    • #893: Implement FusedIterator for NamespaceBindingsIter.
    • #893: Make NamespaceResolver public.
    • #893: Add NsReader::resolver() for access to namespace resolver.

    Misc Changes

    • #893: Rename PrefixIter to NamespaceBindingsIter.
    Open source →
  13. 0.38.1 04 Aug 2025
    Release notes

    Important changes

    To get text in events according to the XML specification (normalized EOLs) use the new methods xml_content() instead of decode(). Deserializer uses new method automatically.

    New Features

    • #882: Add new methods to create Deserializer from existing NsReader:
      • Deserializer::borrowing
      • Deserializer::borrowing_with_resolver
      • Deserializer::buffering
      • Deserializer::buffering_with_resolver
    • #878: Add ability to serialize structs in $value fields. The struct name will be used as a tag name. Previously only enums was allowed there.
    • #806: Add BytesText::xml_content, BytesCData::xml_content and BytesRef::xml_content methods which returns XML EOL normalized strings.
    • #806: Add BytesText::html_content, BytesCData::html_content and BytesRef::html_content methods which returns HTML EOL normalized strings.

    Bug Fixes

    • #806: Properly normalize EOL characters in Deserializer.
    • #888: Properly split attribute values by items when deserialize attribute into list of values and attribute requires decoding.
    Open source →
  14. 0.38.0 28 Jun 2025
    Release notes

    Significant changes

    Now references to entities (as predefined, such as &lt;, as user-defined) reported as a new Event::GeneralRef. Caller can parse the content of the entity and stream events from it as it is required by the XML specification. See the updated custom_entities example!

    Implement whitespace behavior in the standard in Deserializer, which says string primitive types should preserve whitespace, while all other primitives have collapse behavior.

    New Features

    • #863: Add Attributes::into_map_access(&str) and Attributes::into_deserializer() when serialize feature is enabled. This will allow do deserialize serde types right from attributes. Both methods returns the same type which implements serde's Deserializer and MapAccess traits.
    • #766: Allow to parse resolved entities as XML fragments and stream events from them.
    • #766: Added new event Event::GeneralRef with content of general entity.
    • #766: Added new configuration option allow_dangling_amp which allows to have a & not followed by ; in the textual data which is required for some applications for compatibility reasons.
    • #285: Add ability to quick_xml::de::Text to access text with trimmed spaces

    Bug Fixes

    • #868: Allow to have both $text and $value special fields in one struct. Previously any text will be recognized as $value field even when $text field is also presented.
    • #868: Skip text events when deserialize a sequence of items overlapped with text (including CDATA).
    • #841: Do not strip xml prefix from the attributes when map them to struct fields in Deserializer.

    Misc Changes

    • #863: Remove From<QName<'a>> for BytesStart<'a> because now BytesStart stores the encoding in which its data is encoded, but QName is a simple wrapper around byte slice.
    • #766: BytesText::unescape and BytesText::unescape_with replaced by BytesText::decode. Now Text events does not contain escaped parts which are reported as Event::GeneralRef.
    Open source →
  15. 0.37.5 27 Apr 2025
    Release notes

    New Features

    • #857: Add BytesCData::decode().
    Open source →
  16. 0.37.4 01 Apr 2025
    Release notes

    Misc Changes

    • #852: Add Debug impl for NsReader and Reader and Clone impl for NsReader
    Open source →
  17. 0.37.3 25 Mar 2025
    Release notes

    New Features

    • #850: Add Attribute::as_bool() method to get an attribute value as a boolean.
    • #850: Add Attributes::has_nil() method to check if attributes has xsi:nil attribute set to true.
    • #497: Handle xsi:nil attribute in serde Deserializer to better process optional fields.
    Open source →
  18. 0.37.2 29 Dec 2024
    Release notes

    New Features

    • #836: Add se::to_utf8_io_writer() helper compatible with std::io::Write and restricted to UTF-8 encoding.
    Open source →
  19. 0.37.1 17 Nov 2024
    Release notes

    New Features

    • #831: Add BytesCData::escaped() fn to construct CDATA events from arbitrary user input.
    Open source →
  20. 0.37.0 27 Oct 2024
    Release notes

    New Features

    • #826: Implement From<String> and From<Cow<str>> for quick_xml::de::Text.
    • #826: Make SimpleTypeDeserializer and SimpleTypeSerializer public.
    • #826: Implement IntoDeserializer for &mut Deserializer.

    Bug Fixes

    • #655: Do not write indent before and after $text fields and those $value fields that are serialized as a text (for example, usize or String).
    • #826: Handle only those boolean representations that are allowed by Xml Schema which is only "true", "1", "false", and "0". Previously the following values also was accepted:
      bool XML content
      true "True", "TRUE", "t", "Yes", "YES", "yes", "y"
      false "False", "FALSE", "f", "No", "NO", "no", "n"

    Misc Changes

    • #227: Split SeError from DeError in the serialize feature. Serialize functions and methods now return SeError.
    • #810: Return std::io::Error from Writer methods.
    • #811: Split NamespaceError and EncodingError from Error.
    • #811: Renamed Error::EscapeError to Error::Escape to match other variants.
    • #811: Narrow down error return type from Error where only one variant is ever returned: attribute related methods on BytesStart and BytesDecl returns AttrError
    • #820: Classify output of the Serializer by returning an enumeration with kind of written data
    • #823: Do not allow serialization of consequent primitives, for example Vec<usize> or Vec<String> in $value fields. They cannot be deserialized back with the same result
    • #827: Make escape and it variants take a impl Into<Cow<str>> argument and implement From<(&'a str, Cow<'a, str>)> on Attribute
    • #826: Removed DeError::InvalidInt, DeError::InvalidFloat and DeError::InvalidBoolean. Now the responsibility for returning the error lies with the visitor of the type. See rationale in https://github.com/serde-rs/serde/pull/2811
    Open source →
  21. 0.36.2 20 Sep 2024
    Release notes

    Bug Fixes

    • #533: Fix incorrect DocType closing bracket detection when parsing with buffered reader
    Open source →
  22. 0.36.1 23 Jul 2024
    Release notes

    New Features

    • #623: Added Reader::stream() that can be used to read arbitrary data from the inner reader while track position for XML reader.
    Open source →
  23. 0.36.0 08 Jul 2024
    Release notes

    Bug Fixes

    • #781: Fix conditions to start CDATA section. Only uppercase <![CDATA[ can start it. Previously any case was allowed.
    • #780: Fixed incorrect .error_position() when encountering syntax error for open or self-closed tag.

    Misc Changes

    • #780: reader::Parser, reader::ElementParser and reader::PiParser moved to the new module parser.
    • #776: Allow to have attributes in the end tag for compatibility reasons with Adobe Flash XML parser.
    Open source →
  24. 0.35.0 29 Jun 2024
    Release notes

    New Features

    • #772: Add reader::Config::allow_unmatched_ends to permit dangling end tags

    Bug Fixes

    • #773: Fixed reporting incorrect end position in Reader::read_to_end family of methods and trimming of the trailing spaces in Reader::read_text when trim_text_start is set and the last event is not a Text event.
    • #771: Character references now allow any number of leading zeroes as it should. As a result, the following variants of quick_xml::escape::EscapeError are removed:
      • TooLongDecimal
      • TooLongHexadecimal
    • #771: Fixed Attribute::unescape_value which does not unescape predefined values since 0.32.0.
    • #774: Fixed regression since 0.33.0: Text event may be skipped in read_event_into() and read_event_into_async() in some circumstances.

    Misc Changes

    • #771: EscapeError::UnrecognizedSymbol renamed to EscapeError::UnrecognizedEntity.
    • #771: Implemented PartialEq for EscapeError.
    • #771: Replace the following variants of EscapeError by InvalidCharRef variant with a new ParseCharRefError inside:
      • EntityWithNull
      • InvalidDecimal
      • InvalidHexadecimal
      • InvalidCodepoint
    Open source →
  25. 0.34.0 24 Jun 2024
    Release notes

    Bug Fixes

    • #751: Fix internal overflow when read 4GB+ files on 32-bit targets using Reader<impl BufRead> readers.

    Misc Changes

    • #760: Attribute::decode_and_unescape_value and Attribute::decode_and_unescape_value_with now accepts Decoder instead of Reader. Use Reader::decoder() to get it.
    • #760: Writer::write_event now consumes event. Use Event::borrow() if you want to keep ownership.
    • #751: Type of Reader::error_position() and Reader::buffer_position() changed from usize to u64.
    • #751: Type alias Span changed from Range<usize> to Range<u64>.
    Open source →
  26. 0.33.0 21 Jun 2024
    Release notes

    New Features

    • #758: Implemented From<QName> for BytesStart and BytesEnd.

    Bug Fixes

    • #755: Fix incorrect missing of trimming all-space text events when trim_text_start = false and trim_text_end = true.

    Misc Changes

    • #650: Change the type of Event::PI to a new dedicated BytesPI type.
    • #759: Make const as much functions as possible:
      • resolve_html5_entity()
      • resolve_predefined_entity()
      • resolve_xml_entity()
      • Attr::key()
      • Attr::value()
      • Attributes::html()
      • Attributes::new()
      • BytesDecl::from_start()
      • Decoder::encoding()
      • Deserializer::get_ref()
      • IoReader::get_ref()
      • LocalName::into_inner()
      • Namespace::into_inner()
      • NsReader::config()
      • NsReader::prefixes()
      • Prefix::into_inner()
      • QName::into_inner()
      • Reader::buffer_position()
      • Reader::config()
      • Reader::decoder()
      • Reader::error_position()
      • Reader::get_ref()
      • SliceReader::get_ref()
      • Writer::get_ref()
      • Writer::new()
    • #763: Hide quick_xml::escape::resolve_html5_entity under escape-html feature again. This function has significant influence to the compilation time (10+ seconds or 5x times)
    Open source →
  27. 0.32.0 10 Jun 2024
    Release notes

    The way to configure parser is changed. Now all configuration is contained in the Config struct and can be applied at once. When serde-types feature is enabled, configuration is serializable.

    The method of reporting positions of errors has changed - use error_position() to get an offset of the error position. For SyntaxErrors the range error_position()..buffer_position() also will represent a span of error.

    The way of resolve entities with unescape_with are changed. Those methods no longer resolve predefined entities.

    New Features

    • #513: Allow to continue parsing after getting new Error::IllFormed.
    • #677: Added methods config() and config_mut() to inspect and change the parser configuration. Previous builder methods on Reader / NsReader was replaced by direct access to fields of config using reader.config_mut().<...>.
    • #684: Added a method Config::enable_all_checks to turn on or off all well-formedness checks.
    • #362: Added escape::minimal_escape() which escapes only & and <.
    • #362: Added BytesCData::minimal_escape() which escapes only & and <.
    • #362: Added Serializer::set_quote_level() which allow to set desired level of escaping.
    • #705: Added NsReader::prefixes() to list all the prefixes currently declared.
    • #629: Added a default case to impl_deserialize_for_internally_tagged_enum macro so that it can handle every attribute that does not match existing cases within an enum variant.
    • #722: Allow to pass owned strings to Writer::create_element. This is breaking change!
    • #275: Added ElementWriter::new_line() which enables pretty printing elements with multiple attributes.
    • #743: Added Deserializer::get_ref() to get XML Reader from serde Deserializer
    • #734: Added helper functions to resolve predefined XML and HTML5 entities:
      • quick_xml::escape::resolve_predefined_entity
      • quick_xml::escape::resolve_xml_entity
      • quick_xml::escape::resolve_html5_entity
    • #753: Added parser for processing instructions: quick_xml::reader::PiParser.
    • #754: Added parser for elements: quick_xml::reader::ElementParser.

    Bug Fixes

    • #622: Fix wrong disregarding of not closed markup, such as lone <.
    • #684: Fix incorrect position reported for Error::IllFormed(DoubleHyphenInComment).
    • #684: Fix incorrect position reported for Error::IllFormed(MissingDoctypeName).
    • #704: Fix empty tags with attributes not being expanded when expand_empty_elements is set to true.
    • #683: Use local tag name when check tag name against possible names for field.
    • #753: Correctly determine end of processing instructions and XML declaration.

    Misc Changes

    • #675: Minimum supported version of serde raised to 1.0.139
    • #675: Rework the quick_xml::Error type to provide more accurate information:
      • Error::EndEventMismatch replaced by IllFormedError::MismatchedEndTag in some cases
      • Error::EndEventMismatch replaced by IllFormedError::UnmatchedEndTag in some cases
      • Error::TextNotFound was removed because not used
      • Error::UnexpectedBang replaced by SyntaxError
      • Error::UnexpectedEof replaced by SyntaxError in some cases
      • Error::UnexpectedEof replaced by IllFormedError in some cases
      • Error::UnexpectedToken replaced by IllFormedError::DoubleHyphenInComment
      • Error::XmlDeclWithoutVersion replaced by IllFormedError::MissingDeclVersion (in #684)
      • Error::EmptyDocType replaced by IllFormedError::MissingDoctypeName (in #684)
    • #684: Changed positions reported for SyntaxErrors: now they are always points to the start of markup (i. e. to the < character) with error. Use error_position() for that.
    • #684: Now <??> parsed as Event::PI with empty content instead of raising syntax error.
    • #684: Now <?xml?> parsed as Event::Decl instead of Event::PI.
    • #362: Now default quote level is QuoteLevel::Partial when using serde serializer.
    • #689: buffer_position() now always report the position the parser last seen. To get an error position use error_position().
    • #738: Add an example of how to deserialize XML elements into Rust enums using an intermediate custom deserializer.
    • #748: Implement Clone for DeEvent, PayloadEvent and Text.
    • #734: Rename NoEntityResolver to PredefinedEntityResolver.
    • #734: No longer resolve predefined entities (lt, gt, apos, quot, amp) in unescape_with family of methods. You should do that by yourself using the methods listed above.
    Open source →
  28. 0.31.0 23 Oct 2023
    Release notes

    MSRV bumped to 1.56! Crate now uses Rust 2021 edition.

    Enum representation was changed (it was buggy anyway) to ensure compatibility with serde >= 1.0.181

    New Features

    • #545: Resolve well-known namespaces (xml and xmlns) to their appropriate URIs. Also, enforce namespace constraints related to these well-known namespaces.
    • #635: Add support for async ElementWriter operations.

    Bug Fixes

    • #660: Fixed incorrect deserialization of xs:lists from empty tags (<tag/> or <tag></tag>). Previously an DeError::UnexpectedEof") was returned in that case
    • #580: Fixed incorrect deserialization of vectors of newtypes from sequences of tags.
    • #661: More string handling of serialized primitive values (booleans, numbers, strings, unit structs, unit variants). <int>123<something-else/></int> is no longer valid content. Previously all data after 123 up to closing tag would be silently skipped.
    • #567: Fixed incorrect deserialization of vectors of enums from sequences of tags.
    • #671: Fixed deserialization of empty simpleTypes (for example, attributes) into Option fields: now they are always deserialized as Some("").

    Misc Changes

    • #643: Bumped MSRV to 1.56. In practice the previous MSRV was incorrect in many cases.
    • #643: Adopted Rust 2021 edition.
    • #545: Added new Error variant -- Error::InvalidPrefixBind.
    • #651: Relax requirement for version of arbitrary dependency -- we're actually compatible with version 1.0.0 and up.
    • #649: Make features linkable and reference them in the docs.
    • #619: Allow to raise application errors in ElementWriter::write_inner_content (and newly added ElementWriter::write_inner_content_async of course).
    • #662: Get rid of some allocations during serde deserialization.
    • #665: Improve serialization of xs:lists when some elements serialized to an empty string.
    • #630: Fixed compatibility with serde >= 1.0.181
    Open source →
  29. 0.30.0 23 Jul 2023
    Release notes

    New Features

    • #609: Added Writer::write_serializable to provide the capability to serialize arbitrary types using serde when using the lower-level Writer API.
    • #615: Added ability to set entity resolver when deserialize using borrowing reader.
    • #617: Added ability to enforce the expansion of empty elements.

    Bug Fixes

    • #604: Avoid crashing on wrong comments like <!--> when using read_event_into* functions.

    Misc Changes

    Open source →
  30. 0.29.0 12 Jun 2023
    Release notes

    New Features

    • #601: Add serde_helper module to the crate root with some useful utility functions and document using of enum's unit variants as a text content of element.
    • #606: Implement indentation for AsyncWrite trait implementations.

    Bug Fixes

    • #603: Fix a regression from #581 that an XML comment or a processing instruction between a <!DOCTYPE> and the root element in the file broke deserialization of structs by returning DeError::ExpectedStart
    • #608: Return a new error Error::EmptyDocType on empty doctype instead of crashing because of a debug assertion.

    Misc Changes

    • #594: Add a helper macro to help deserialize internally tagged enums with Serde, which doesn't work out-of-the-box due to serde limitations.
    Open source →
  31. 0.28.2 12 Apr 2023
    Release notes

    New Features

    • #581: Allow Deserializer to set quick_xml::de::EntityResolver for resolving unknown entities that would otherwise cause the parser to return an [EscapeError::UnrecognizedSymbol] error.

    Misc Changes

    • #584: Export EscapeError from the crate
    • #581: Relax requirements for unsescape_* set of functions -- their now use FnMut instead of Fn for resolve_entity parameters, like Iterator::map from std.
    Open source →
  32. 0.28.1 19 Mar 2023
    Release notes

    Misc Changes

    • #579: ElementWriter.write_inner_content now uses a FnOnce instead of a more restrictive Fn closure
    Open source →
  33. 0.28.0 13 Mar 2023
    Release notes

    New Features

    • #541: (De)serialize specially named $text enum variant in externally tagged enums to / from textual content
    • #556: to_writer and to_string now accept ?Sized types
    • #556: Add new to_writer_with_root and to_string_with_root helper functions
    • #520: Add methods BytesText::inplace_trim_start and BytesText::inplace_trim_end to trim leading and trailing spaces from text events
    • #565: Allow deserialize special field names $value and $text into borrowed fields when use serde deserializer
    • #568: Rename Writer::inner into Writer::get_mut
    • #568: Add method Writer::get_ref
    • #569: Rewrite the Reader::read_event_into_async as an async fn, making the future Send if possible.
    • #571: Borrow element names (<element>) when deserialize with serde. This change allow to deserialize into HashMap<&str, T>, for example
    • #573: Add basic support for async byte writers via tokio's AsyncWrite.

    Bug Fixes

    • #537: Restore ability to deserialize attributes that represents XML namespace mappings (xmlns:xxx) that was broken since #490
    • #510: Fix an error of deserialization of Option<T> fields where T is some sequence type (for example, Vec or tuple)
    • #540: Fix a compilation error (probably a rustc bug) in some circumstances. Serializer::new and Serializer::with_root now accepts only references to Writer.
    • #520: Merge consequent (delimited only by comments and processing instructions) texts and CDATA when deserialize using serde deserializer. DeEvent::Text and DeEvent::CData events was replaced by DeEvent::Text with merged content. The same behavior for the Reader does not implemented (yet?) and should be implemented manually
    • #562: Correctly set minimum required version of memchr dependency to 2.1
    • #565: Correctly set minimum required version of tokio dependency to 1.10
    • #565: Fix compilation error when build with serde <1.0.139
    Open source →
  34. 0.27.1 28 Dec 2022
    Release notes

    Bug Fixes

    • #530: Fix an infinite loop leading to unbounded memory consumption that occurs when skipping events on malformed XML with the overlapped-lists feature active.
    • #530: Fix an error in the Deserializer::read_to_end when overlapped-lists feature is active and malformed XML is parsed
    Open source →
  35. 0.27.0 25 Dec 2022
    Release notes

    New Features

    • #521: Implement Clone for all error types. This required changing Error::Io to contain Arc<std::io::Error> instead of std::io::Error since std::io::Error does not implement Clone.

    Bug Fixes

    • #490: Ensure that serialization of map keys always produces valid XML names. In particular, that means that maps with numeric and numeric-like keys (for example, "42") no longer can be serialized because XML name cannot start from a digit
    • #500: Fix deserialization of top-level sequences of enums, like
      <?xml version="1.0" encoding="UTF-8"?>
      <!-- list of enum Enum { A, B, С } -->
      <A/>
      <B/>
      <C/>
      
    • #514: Fix wrong reporting Error::EndEventMismatch after disabling and enabling .check_end_names
    • #517: Fix swapped codes for \r and \n characters when escaping them
    • #523: Fix incorrect skipping text and CDATA content before any map-like structures in serde deserializer, like
      unwanted text<struct>...</struct>
      
    • #523: Fix incorrect handling of xs:lists with encoded spaces: they still act as delimiters, which is confirmed also by mature XmlBeans Java library
    • #473: Fix a hidden requirement to enable serde's derive feature to get quick-xml's serialize feature for edition = 2021 or resolver = 2 crates

    Misc Changes

    • #490: Removed $unflatten= special prefix for fields for serde (de)serializer, because:

      • it is useless for deserializer
      • serializer was rewritten and does not require it anymore

      This prefix allowed you to serialize struct field as an XML element and now replaced by a more thoughtful system explicitly indicating that a field should be serialized as an attribute by prepending @ character to its name

    • #490: Removed $primitive= prefix. That prefix allowed you to serialize struct field as an attribute instead of an element and now replaced by a more thoughtful system explicitly indicating that a field should be serialized as an attribute by prepending @ character to its name

    • #490: In addition to the $value special name for a field a new $text special name was added:

      • $text is used if you want to map field to text content only. No markup is expected (but text can represent a list as defined by xs:list type)
      • $value is used if you want to map elements with different names to one field, that should be represented either by an enum, or by sequence of enums (Vec, tuple, etc.), or by string. Use it when you want to map field to any content of the field, text or markup

      Refer to documentation for details.

    • #521: MSRV bumped to 1.52.

    • #473: serde feature that used to make some types serializable, renamed to serde-types

    • #528: Added documentation for XML to serde mapping

    Open source →
  36. 0.26.0 23 Oct 2022
    Release notes

    Misc Changes

    • #481: Removed the uses of const fn added in version 0.24 in favor of a lower minimum supported Rust version (1.46.0). Minimum supported Rust version is now verified in the CI.
    • #489: Reduced the size of the package uploaded into the crates.io by excluding tests, examples, and benchmarks.
    Open source →
  37. 0.25.0 10 Sep 2022
    Release notes

    Bug Fixes

    • #469: Fix incorrect parsing of CDATA and comments when using buffered readers

    Misc Changes

    • #468: Content of DeError::Unsupported changed from &'static str to Cow<'static, str>
    • #468: Ensure that map keys are restricted to only types that can be serialized as primitives
    Open source →
  38. 0.24.1 10 Sep 2022
    Release notes

    Bug Fixes

    • #469: Fix incorrect parsing of CDATA and comments when using buffered readers
    Open source →
  39. 0.24.0 28 Aug 2022 withdrawn
    Release notes

    New Features

    • #387: Allow overlapping between elements of sequence and other elements (using new feature overlapped-lists)
    • #393: New module name with QName, LocalName, Namespace, Prefix and PrefixDeclaration wrappers around byte arrays and ResolveResult with the result of namespace resolution
    • #180: Make Decoder struct public. You already had access to it via the Reader::decoder() method, but could not name it in the code. Now the preferred way to access decoding functionality is via this struct
    • #395: Add support for XML Schema xs:list
    • #324: Reader::from_str / Deserializer::from_str / from_str now ignore the XML declared encoding and always use UTF-8
    • #416: Add borrow() methods in all event structs which allows to get a borrowed version of any event
    • #437: Split out namespace reading functionality to a dedicated NsReader, namely:
      Old function in Reader New function in NsReader
      read_event -- borrow from input
      read_resolved_event -- borrow from input
      read_event_into
      read_namespaced_event read_resolved_event_into
      resolve
      event_namespace resolve_element
      attribute_namespace resolve_attribute
    • #439: Added utilities detect_encoding() and decode() under the quick-xml::encoding namespace.
    • #450: Added support of asynchronous tokio readers
    • #455: Change return type of all read_to_end* methods to return a span between tags
    • #455: Added Reader::read_text method to return a raw content (including markup) between tags
    • #459: Added a Writer::write_bom() method for inserting a Byte-Order-Mark into the document.
    • #467: The following functions made const:
      • Attr::key
      • Attr::value
      • Attributes::html
      • Attributes::new
      • BytesDecl::from_start
      • Decoder::encoding
      • LocalName::into_inner
      • Namespace::into_inner
      • Prefix::into_inner
      • QName::into_inner
      • Reader::buffer_position
      • Reader::decoder
      • Reader::get_ref
      • Serializer::new
      • Serializer::with_root
      • Writer::new

    Bug Fixes

    • #9: Deserialization erroneously was successful in some cases where error is expected. This broke deserialization of untagged enums which rely on error if variant cannot be parsed
    • #387: Allow to have an ordinary elements together with a $value field
    • #387: Internal deserializer state can be broken when deserializing a map with a sequence field (such as Vec<T>), where elements of this sequence contains another sequence. This error affects only users with the serialize feature enabled
    • #393: Now event_namespace, attribute_namespace and read_event_namespaced returns ResolveResult::Unknown if prefix was not registered in namespace buffer
    • #393: Fix breaking processing after encounter an attribute with a reserved name (started with "xmlns")
    • #363: Do not generate empty Event::Text events
    • #412: Fix using incorrect encoding if read_to_end family of methods or read_text method not found a corresponding end tag and reader has non-UTF-8 encoding
    • #421: Fix incorrect order of unescape and decode operations for serde deserializer: decoding should be first, unescape is the second
    • #421: Fixed unknown bug in serde deserialization of externally tagged enums when an enum variant represented as a Text event (i.e. <xml>tag</xml>) and a document encoding is not an UTF-8
    • #434: Fixed incorrect error generated in some cases by serde deserializer
    • #445: Use local name without namespace prefix when selecting enum variants based on element names in a serde deserializer

    Misc Changes

    • #8: Changes in the error type DeError:

      Variant Change
      DeError::Text Removed because never raised
      DeError::InvalidEnum Removed because never raised
      DeError::Xml Renamed to DeError::InvalidXml for consistency with DeError::InvalidBoolean
      DeError::Int Renamed to DeError::InvalidInt for consistency with DeError::InvalidBoolean
      DeError::Float Renamed to DeError::InvalidFloat for consistency with DeError::InvalidBoolean
      DeError::Start Renamed to DeError::UnexpectedStart and tag name added to an error
      DeError::End Renamed to DeError::UnexpectedEnd and tag name added to an error
      DeEvent::Eof Renamed to DeError::UnexpectedEof
      DeError::EndOfAttributes Renamed to DeError::KeyNotFound
      DeError::ExpectedStart Added
    • #391: Added code coverage

    • #393: event_namespace and attribute_namespace now accept QName and returns ResolveResult and LocalName, read_event_namespaced now returns ResolveResult instead of Option<[u8]>

    • #393: Types of Attribute::key and Attr::key() changed to QName

    • #393: Now BytesStart::name() and BytesEnd::name() returns QName, and BytesStart::local_name() and BytesEnd::local_name() returns LocalName

    • #191: Remove unused reader.decoder().decode_owned(). If you ever used it, use String::from_utf8 instead (which that function did)

    • #191: Remove *_without_bom methods from the Attributes struct because they are useless. Use the same-named methods without that suffix instead. Attribute values cannot contain BOM

    • #191: Remove Reader::decode() and Reader::decode_without_bom(), they are replaced by Decoder::decode() and nothing. Use reader.decoder().decode_*(...) instead of reader.decode_*(...) for now. Reader::encoding() is replaced by Decoder::encoding() as well

    • #180: Eliminated the differences in the decoding API when feature encoding enabled and when it is disabled. Signatures of functions are now the same regardless of whether or not the feature is enabled, and an error will be returned instead of performing replacements for invalid characters in both cases.

      Previously, if the encoding feature was enabled, decoding functions would return Result<Cow<&str>> while without this feature they would return Result<&str>. With this change, only Result<Cow<&str>> is returned regardless of the status of the feature.

    • #180: Error variant Error::Utf8 replaced by Error::NonDecodable

    • #118: Remove BytesStart::unescaped* set of methods because they could return wrong results Use methods on Attribute instead

    • #403: Remove deprecated quick_xml::de::from_bytes and Deserializer::from_borrowing_reader

    • #412: Rename methods of Reader:

      Old Name New Name
      read_event read_event_into
      read_to_end read_to_end_into
      read_text read_text_into
      read_event_unbuffered read_event
      read_to_end_unbuffered read_to_end
    • #412: Change read_to_end* and read_text_into to accept QName instead of AsRef<[u8]>

    • #415: Changed custom entity unescaping API to accept closures rather than a mapping of entity to replacement text. This avoids needing to allocate a map and provides the user with more flexibility.

    • #415: Renamed functions for consistency across the API:

      Old Name New Name
      *_with_custom_entities *_with
      BytesText::unescaped() BytesText::unescape()
      Attribute::unescaped_* Attribute::unescape_*
    • #329: Also, that functions now borrow from the input instead of event / attribute

    • #416: BytesStart::to_borrowed renamed to BytesStart::borrow, the same method added to all events

    • #421: decode_and_unescape* methods now does one less allocation if unescaping is not required

    • #421: Removed ability to deserialize byte arrays from serde deserializer. XML is not able to store binary data directly, you should always use some encoding scheme, for example, HEX or Base64

    • #421: All unescaping functions now accepts and returns strings instead of byte slices

    • #423: All escaping functions now accepts and returns strings instead of byte slices

    • #423: Removed BytesText::from_plain because it internally did escaping of a byte array, but since now escaping works on strings. Use BytesText::new instead

    • #428: Removed BytesText::escaped(). Use .as_ref() provided by Deref impl instead.

    • #428: Removed BytesText::from_escaped(). Use constructors from strings instead, because writer anyway works in UTF-8 only

    • #428: Removed BytesCData::new(). Use constructors from strings instead, because writer anyway works in UTF-8 only

    • #428: Changed the event and Attributes constructors to accept a &str slices instead of &[u8] slices. Handmade events has always been assumed to store their content UTF-8 encoded.

    • #428: Removed Decoder parameter from _and_decode versions of functions for BytesText (remember, that those functions was renamed in #415).

    • #431: Changed event constructors:

      Old names New name
      BytesStart::owned_name(impl Into<Vec<u8>>) BytesStart::new(impl Into<Cow<str>>)
      BytesStart::borrowed_name(&[u8]) (as above)
      BytesStart::owned(impl Into<Vec<u8>>, usize) BytesStart::from_content(impl Into<Cow<str>>, usize)
      BytesStart::borrowed(&[u8], usize) (as above)
      BytesEnd::owned(Vec<u8>) BytesEnd::new(impl Into<Cow<str>>)
      BytesEnd::borrowed(&[u8]) (as above)
      BytesText::from_escaped(impl Into<Cow<[u8]>>) BytesText::from_escaped(impl Into<Cow<str>>)
      BytesText::from_escaped_str(impl Into<Cow<str>>) (as above)
      BytesText::from_plain(&[u8]) BytesText::new(&str)
      BytesText::from_plain_str(&str) (as above)
      BytesCData::new(impl Into<Cow<[u8]>>) BytesCData::new(impl Into<Cow<str>>)
      BytesCData::from_str(&str) (as above)
    • #440: Removed Deserializer::from_slice and quick_xml::de::from_slice methods because deserializing from a byte array cannot guarantee borrowing due to possible copying while decoding.

    • #455: Removed Reader::read_text_into which is just a thin wrapper over match on Event::Text

    • #456: Reader and writer stuff grouped under reader and writer modules. You still can use re-exported definitions from a crate root

    • #459: Made the Writer::write() method non-public as writing random bytes to a document is not generally useful or desirable.

    • #459: BOM bytes are no longer emitted as Event::Text. To write a BOM, use Writer::write_bom().

    • #467: Removed Deserializer::new because it cannot be used outside of the quick-xml crate

    New Tests

    • #9: Added tests for incorrect nested tags in input
    • #387: Added a bunch of tests for sequences deserialization
    • #393: Added more tests for namespace resolver
    • #393: Added tests for reserved names (started with "xml"i) -- see https://www.w3.org/TR/xml-names11/#xmlReserved
    • #363: Add tests for Reader::read_event_impl to ensure that proper events generated for corresponding inputs
    • #407: Improved benchmark suite to cover whole-document parsing, escaping and unescaping text
    • #418: Parameterized macrobenchmarks and comparative benchmarks, added throughput measurements via criterion
    • #434: Added more tests for serde deserializer
    • #443: Now all documents in /tests/documents are checked out with LF eol in working copy (except sample_5_utf16bom.xml)

    Legend:

    • feat: A new feature
    • fix: A bug fix
    • docs: Documentation only changes
    • style: White-space, formatting, missing semi-colons, etc
    • refactor: A code change that neither fixes a bug nor adds a feature
    • perf: A code change that improves performance
    • test: Adding missing tests
    • chore: Changes to the build process or auxiliary tools/libraries/documentation
    Open source →
  40. 0.23.1 10 Sep 2022
    Release notes

    Bug Fixes

    • #469: Fix incorrect parsing of CDATA and comments when using buffered readers
    Open source →
  41. 0.23.0 25 May 2022 withdrawn
    Release notes
    • feat: add support for i128 / u128 in attributes or text/CDATA content
    • test: add tests for malformed inputs for serde deserializer
    • fix: allow to deserialize units from any data in attribute values and text nodes
    • refactor: unify errors when EOF encountered during serde deserialization
    • test: ensure that after deserializing all XML was consumed
    • feat: add Deserializer::from_str, Deserializer::from_slice and Deserializer::from_reader
    • refactor: deprecate from_bytes and Deserializer::from_borrowing_reader because they are fully equivalent to from_slice and Deserializer::new
    • refactor: reduce number of unnecessary copies when deserialize numbers/booleans/identifiers from the attribute and element names and attribute values
    • fix: allow to deserialize units from text and CDATA content. DeError::InvalidUnit variant is removed, because after fix it is no longer used
    • fix: ElementWriter, introduced in #274 (0.23.0-alpha2) now available to end users
    • fix: allow lowercase <!doctype > definition (used in HTML 5) when parse document from &[u8]
    • test: add tests for consistence behavior of buffered and borrowed readers
    • fix: produce consistent error positions in buffered and borrowed readers
    • feat: Error::UnexpectedBang now provide the byte found
    • refactor: unify code for buffered and borrowed readers
    • fix: fix internal panic message when parse malformed XML (#344)
    • test: add tests for trivial documents (empty / only comment / <root>...</root> -- one tag with content)
    • fix: CDATA was not handled in many cases where it should
    • fix: do not unescape CDATA content because it never escaped by design. CDATA event data now represented by its own BytesCData type (quick-xml#311)
    • feat: add Reader::get_ref() and Reader::get_mut(), rename Reader::into_underlying_reader() to Reader::into_inner()
    • refactor: now Attributes::next() returns a new type AttrError when attribute parsing failed (#4)
    • test: properly test all paths of attributes parsing (#4)
    • feat: attribute iterator now implements FusedIterator (#4)
    • fix: fixed many errors in attribute parsing using iterator, returned from attributes() or html_attributes() (#4)
    Open source →
  42. 0.23.0-alpha3 21 Aug 2021 pre-release
    Release notes
    • fix: use element name (with namespace) when unflattening (serialize feature)
    Open source →
  43. 0.23.0-alpha2 14 Aug 2021 pre-release
    Release notes
    • fix: failing tests with features
    Open source →
  44. 0.23.0-alpha1 10 Aug 2021 pre-release
    Release notes
    • style: convert to rust edition 2018
    • fix: don't encode multi byte escape characters as big endian
    • feat: add Writer::write_nested_event
    • feat: add BytesStart::try_get_attribute
    • test: add more test on github actions
    • feat: allow unbuffered deserialization (!!)
    • style: use edition 2018
    • feat: add a function for partially escaping an element
    • feat: higher level api to write xmls
    Open source →
  45. 0.22.0 23 Feb 2021
    Release notes
    • feat (breaking): Move html entity escape behind a 'escape-html' feature to help with compilation
    • style: rustfmt
    • feat: inline CData when pretty printing
    • test: fix tests (Windows and Html5)
    • feat (breaking): add *_with_custom_entities versions of all `unescape_*\ methods
    • test: more robust test for numeric entities
    • refactor: add explicit pre-condition about custom_entities
    Open source →
  46. 0.21.0 03 Feb 2021
    Release notes
    • feat: Split text trim into start and end
    • fix: $value rename should work the same for deserialization and serialization
    • docs: README.md: Replace dead benchmark link
    • style: Cargo.toml: remove "readme" field
    • fix: Parse & in cdata correctly
    • style: Fix reader.rs typo
    • feat: Accept html5 doctype
    • fix: Unescape all existing HTML entities
    Open source →
  47. 0.20.0 17 Oct 2020
    Release notes
    • test: Add tests for indentation
    • test: Add complete tests for serde deserialization
    • feat: Use self-closed tags when serialize types without nested elements with serde
    • feat: Add two new API to the BytesStart: to_borrowed() and to_end()
    • feat: Add ability to specify name of the root tag and indentation settings when serialize type with serde
    • feat: Add support for serialization of
      • unit enums variants
      • newtype structs and enum variants
      • unnamed tuples, tuple structs and enum variants
    • fix: More consistent structs serialization
    • fix: Deserialization of newtype structs
    • fix: unit deserialization and newtype and struct deserialization in adjacently tagged enums
    Open source →
  48. 0.19.0 26 Sep 2020
    Release notes
    • docs: Add example for nested parsing
    • fix: buffer_position not properly set sometimes
    • feat: Make escape module public apart from EscapeError
    • feat: Nake Reader Cloneable
    • feat: Enable writing manual indentation (and fix underflow on shrink)
    • style: Forbid unsafe code
    • fix: Use write_all instead of write
    • fix: (Serde) Serialize basic types as attributes (breaking change)
    • test: Fix benchmarks on Windows and add trimmed variant
    • feat: deserialize bytes
    Open source →
  49. 0.18.1 15 Mar 2020

    Nothing published for this version

  50. 0.18.0 15 Mar 2020
    Release notes
    • feat: add decode_without_bom fns for BOM prefixed text fields
    • fix: decode then unescape instead of unescape and decode
    Open source →
  51. 0.17.2 17 Dec 2019
    Release notes
    • feat: add Seq to serializer
    • docs: update readme with example for $value
    Open source →
  52. 0.17.1 11 Dec 2019
    Release notes
    • feat: add new serialize feature to support serde serialize/deserialize
    Open source →
  53. 0.17.0 11 Oct 2019
    Release notes
    • perf: speed up (un)escape a little
    • feat: remove failure completely (breaking change) and implement std::error::Error for Error
    • feat: improve Debugs for Attribute, BytesStart, BytesEnd, BytesText
    Open source →
  54. 0.16.1 02 Sep 2019
    Release notes
    • refactor: remove derive_more dependency (used only in 2 structs)
    • refactor: move xml-rs bench dependency into another local crate
    Open source →
  55. 0.16.0 24 Aug 2019
    Release notes
    • feat: (breaking change) set failure and encoding_rs crates as optional. You should now use respectively use-failure and encoding features to get the old behavior
    • perf: improve perf using memchr3 iterator. Reading is 18% better on benches
    Open source →
  56. 0.15.0 15 Jul 2019
    Release notes
    • feat: remove Seek bound
    • style: rustfmt
    Open source →
  57. 0.14.0 08 Apr 2019
    Release notes
    • feat: make failure error crate optional. To revert back to old behavior, use the --failure feature.
    Open source →
  58. 0.13.3 20 Feb 2019
    Release notes
    • feat: allow changing name without deallocating BytesStart buffer
    • feat: add standard error type conversion
    Open source →
  59. 0.13.2 12 Jan 2019
    Release notes
    • fix: allow whitespace in End events
    • feat: bump dependencies
    Open source →
  60. 0.13.1 23 Oct 2018
    Release notes
    • feat: Add into_underlying_reader method for Reader<BufRead + Seek>
    Open source →

Every package, every release, already written down.

The archive is open and free. Watching your own project is what we are building next.

Browse the archive