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 2026Releases
latest 60 of 104-
0.42.022 Aug 2026Release notes
Open source →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&strandStringtypes where possible instead of
&[u8]andVec<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 toReader::from_reader()withoutDecodingReaderwill now
produceError::Encodinginstead of silently passing through invalid bytes.
UseDecodingReaderto transcode non-UTF-8 sources. - #963: Name types (
QName,LocalName,Prefix,Namespace,PrefixDeclaration)
now wrap&strinstead of&[u8].into_inner()returns&str, andAsRef<str>
is implemented (AsRef<[u8]>has been removed).ResolveResult::Unknownnow containsString
instead ofVec<u8>, andNamespaceErrorvariants containStringinstead ofVec<u8>. - #963: Removed the
decoder: Decoderfield from event types (BytesStart,BytesText,
BytesCData,BytesRef) andAttributes. Thedecoder()method is no longer available
on these types. Decode methods on events now always assume UTF-8 input.
Error::missed_end()no longer takes aDecoderparameter. - #963: Event types (
BytesStart,BytesEnd,BytesText,BytesCData,BytesPI,
BytesRef) now storeCow<str>internally instead ofCow<[u8]>.into_inner()on
BytesText,BytesCData,BytesPI, andBytesRefnow returnsCow<str>.
BytesStart::set_name()now takes&strinstead of&[u8]. - #963: All event types and the
Eventenum now implementDeref<Target = str>
instead ofDeref<Target = [u8]>. ExplicitAsRef<str>impls are provided to
avoid ambiguity. - #963: Removed
decode()methods fromBytesText,BytesCData, andBytesRef.
Content is already available as&strviaDeref. Thexml10_content(),
xml11_content(),xml_content(), andhtml_content()methods now return
Cow<str>directly instead ofResult<Cow<str>, EncodingError>. - #963:
Attribute::valueis nowCow<'a, str>instead ofCow<'a, [u8]>.
TheFrom<(&[u8], &[u8])>impl has been removed. - #963:
BytesDecl::version(),encoding(), andstandalone()now return
Cow<'_, str>instead ofCow<'_, [u8]>. - #963: Removed
Reader::decoder()method. UseReader::encoding()instead
(available with theencodingfeature). Removeddecoder()from theXmlRead
serde trait. Removed all methods fromDecoder(the struct is kept only for
backward compatibility with deprecatedAttributemethods). - #980:
NamespaceError::TooManyDeclarationshas been renamed toTooManyBindings,
andNamespaceResolver::set_max_declarations_per_elementhas 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::UnexpectedStartrenamed toDeError::MixedContent. That error
is emitted when you try to deserialize boolean, number or stringfieldfrom
something like<field>text <tag/> another text</field>.
Bug Fixes
- #670: Serde serializer now escapes
\r,\n, and\tin attribute values
as , , and	respectively, preventing silent data loss from
XML attribute-value normalization on round-trip. LikewiseAttribute::from
performs the same transformation. - #953: The serde
Deserializernow 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::newandAttributes::htmlnow return empty iterators when
their starting position is past the end of the input instead of panicking. - #977:
NamespaceResolver::push(and hence everyNsReaderStart/Empty
event) now returns the newNamespaceError::TooDeeplyNestedwhen a document
nests elements deeper thanu16::MAX, instead of overflowing the internal
u16depth counter. Previously the unguardednesting_level += 1panicked
underoverflow-checksbuilds and silently wrapped in release, corrupting
namespace-scope bookkeeping on deeply nested untrusted input. - #980:
NamespaceResolvernow caps the total number of in-scope namespace
bindings (default 128, configurable viaset_max_namespace_bindings),
replacing the previous per-elementmax_declarations_per_elementlimit. - #978: The serde
Deserializernow enforces a configurable recursion-depth
limit (default 128, matchingserde_json). Deeply nested XML returns
DeError::TooDeeplyNestedinstead of overflowing the native call stack.
UseDeserializer::recursion_limit()to adjust. - #990:
\rin text content is now escaped as by the serde serializer,
BytesText::new(),escape(),partial_escape(), andminimal_escape(),
preventing silent conversion to\nfrom XML end-of-line normalization on
round-trip. Note that\rcannot 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 anexamples/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
Attributemethods that take aDecoderparameter, 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(). Usenormalized_value()and
normalized_value_with()instead. - #1002: Added
NamespaceResolver::withthat 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::resolverandDeserializer::resolver_mutmethods
to get a namespace resolver used by this deserializer, because it no longer uses
anNsReaderinternally. - #1005: Implement
Hash,PartialOrd, andOrdforBytesTextandBytesCDatatypes.
New Contributors
- @maxtaran2010 made their first contribution in #976
- @scadastrangelove made their first contribution in #979
- @lntutor made their first contribution in #992
Full Changelog: v0.41.0...v0.42.0
Release notes
Open source →This is a large release. The primary change is an ergonomic improvement across the entire API - quick_xml now makes use of
&strandStringtypes where possible instead of&[u8]andVec<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()withoutDecodingReaderwill now produceError::Encodinginstead of silently passing through invalid bytes. UseDecodingReaderto transcode non-UTF-8 sources. - #963: Name types (
QName,LocalName,Prefix,Namespace,PrefixDeclaration) now wrap&strinstead of&[u8].into_inner()returns&str, andAsRef<str>is implemented (AsRef<[u8]>has been removed).ResolveResult::Unknownnow containsStringinstead ofVec<u8>, andNamespaceErrorvariants containStringinstead ofVec<u8>. - #963: Removed the
decoder: Decoderfield from event types (BytesStart,BytesText,BytesCData,BytesRef) andAttributes. Thedecoder()method is no longer available on these types. Decode methods on events now always assume UTF-8 input.Error::missed_end()no longer takes aDecoderparameter. - #963: Event types (
BytesStart,BytesEnd,BytesText,BytesCData,BytesPI,BytesRef) now storeCow<str>internally instead ofCow<[u8]>.into_inner()onBytesText,BytesCData,BytesPI, andBytesRefnow returnsCow<str>.BytesStart::set_name()now takes&strinstead of&[u8]. - #963: All event types and the
Eventenum now implementDeref<Target = str>instead ofDeref<Target = [u8]>. ExplicitAsRef<str>impls are provided to avoid ambiguity. - #963: Removed
decode()methods fromBytesText,BytesCData, andBytesRef. Content is already available as&strviaDeref. Thexml10_content(),xml11_content(),xml_content(), andhtml_content()methods now returnCow<str>directly instead ofResult<Cow<str>, EncodingError>. - #963:
Attribute::valueis nowCow<'a, str>instead ofCow<'a, [u8]>. TheFrom<(&[u8], &[u8])>impl has been removed. - #963:
BytesDecl::version(),encoding(), andstandalone()now returnCow<'_, str>instead ofCow<'_, [u8]>. - #963: Removed
Reader::decoder()method. UseReader::encoding()instead (available with theencodingfeature). Removeddecoder()from theXmlReadserde trait. Removed all methods fromDecoder(the struct is kept only for backward compatibility with deprecatedAttributemethods). - #980:
NamespaceError::TooManyDeclarationshas been renamed toTooManyBindings, andNamespaceResolver::set_max_declarations_per_elementhas been renamed toNamespaceResolver::set_max_namespace_bindings, and the semantic behavior has changed slightly. The default maximum has also been reduced from 256 to 128. - #1000:
DeError::UnexpectedStartrenamed toDeError::MixedContent. That error is emitted when you try to deserialize boolean, number or stringfieldfrom something like<field>text <tag/> another text</field>.
Bug Fixes
- #670: Serde serializer now escapes
\r,\n, and\tin attribute values as , , and	respectively, preventing silent data loss from XML attribute-value normalization on round-trip. LikewiseAttribute::fromperforms the same transformation. - #953: The serde
Deserializernow 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::newandAttributes::htmlnow return empty iterators when their starting position is past the end of the input instead of panicking. - #977:
NamespaceResolver::push(and hence everyNsReaderStart/Emptyevent) now returns the newNamespaceError::TooDeeplyNestedwhen a document nests elements deeper thanu16::MAX, instead of overflowing the internalu16depth counter. Previously the unguardednesting_level += 1panicked underoverflow-checksbuilds and silently wrapped in release, corrupting namespace-scope bookkeeping on deeply nested untrusted input. - #980:
NamespaceResolvernow caps the total number of in-scope namespace bindings (default 128, configurable viaset_max_namespace_bindings), replacing the previous per-elementmax_declarations_per_elementlimit. - #978: The serde
Deserializernow enforces a configurable recursion-depth limit (default 128, matchingserde_json). Deeply nested XML returnsDeError::TooDeeplyNestedinstead of overflowing the native call stack. UseDeserializer::recursion_limit()to adjust. - #990:
\rin text content is now escaped as by the serde serializer,BytesText::new(),escape(),partial_escape(), andminimal_escape(), preventing silent conversion to\nfrom XML end-of-line normalization on round-trip. Note that\rcannot 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 anexamples/README.mdguide 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
Attributemethods that take aDecoderparameter, since attribute values are now always valid UTF-8:decoded_and_normalized_value(),decoded_and_normalized_value_with(),decode_and_unescape_value(), anddecode_and_unescape_value_with(). Usenormalized_value()andnormalized_value_with()instead. - #1002: Added
NamespaceResolver::withthat 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::resolverandDeserializer::resolver_mutmethods to get a namespace resolver used by this deserializer, because it no longer uses anNsReaderinternally. - #1005: Implement
Hash,PartialOrd, andOrdacross allBytes*types.
- #963: Reader now validates that input is valid UTF-8 when constructing events.
-
0.41.029 Jun 2026Release notes
Open source →What's Changed
New Features
- #970: Add
NsReader::resolver_mut()andNamespaceResolver::{max_declarations_per_element, set_max_declarations_per_element}.
Bug Fixes
- #969:
Attributes(and anything that iteratesBytesStart::attributes()with the defaultwith_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 exactAttrError::Duplicated(new, prev)positions are unchanged. - #970:
NamespaceResolver::push(and hence everyNsReaderStart/Emptyevent) now rejects a start tag that declares more thanDEFAULT_MAX_DECLARATIONS_PER_ELEMENT(256)xmlns/xmlns:*namespace bindings, returning the newNamespaceError::TooManyDeclarations. Previouslypushallocated oneNamespaceBindingper declaration with no upper bound, before the event was returned to the caller, so anNsReaderconsumer could not bound its memory exposure on untrusted input. The limit is configurable viaNamespaceResolver::set_max_declarations_per_element(useusize::MAXto disable).
New Contributors
- @qifan-sailboat made their first contribution in #972
Full Changelog: v0.40.1...v0.41.0
Release notes
Open source →New Features
- #970: Add
NsReader::resolver_mut()andNamespaceResolver::{max_declarations_per_element, set_max_declarations_per_element}.
Bug Fixes
- #969:
Attributes(and anything that iteratesBytesStart::attributes()with the defaultwith_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 exactAttrError::Duplicated(new, prev)positions are unchanged. - #970:
NamespaceResolver::push(and hence everyNsReaderStart/Emptyevent) now rejects a start tag that declares more than 256xmlns/xmlns:*namespace bindings, returning the newNamespaceError::TooManyDeclarations. Previouslypushallocated oneNamespaceBindingper declaration with no upper bound, before the event was returned to the caller, so anNsReaderconsumer could not bound its memory exposure on untrusted input. The limit is configurable viaNamespaceResolver::set_max_declarations_per_element(useusize::MAXto disable).
- #970: Add
-
0.40.115 May 2026Release notes
Open source →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 breakdrain_text's consecutive-text merge, so twoDeEvent::Textevents reachedread_textand 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
- @williamareynolds made their first contribution in #964
Full Changelog: v0.40.0...v0.40.1
Release notes
Open source →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 breakdrain_text's consecutive-text merge, so twoDeEvent::Textevents reachedread_textand 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.
- #964: Fix
-
0.40.011 May 2026Release notes
Open source →What's Changed
MSRV bumped to 1.79.
Now
quick-xmlsupports the UTF-16 and ISO-2022-JP encoded documents. See the newDecodingReadertype.New Features
-
#956: Add
DecodingReader, aBufReadadapter that auto-detects encoding from BOM or XML declaration and transcodes to UTF-8. Enabled by theencodingfeature. -
#938: Add new enumeration
XmlVersionand typified getterBytesDecl::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
Deserializerwhen parse XML 1.0 documents. Previously XML 1.1. rules was applied.
Misc Changes
- #914: Remove deprecated
.prefixes(),.resolve(),.resolve_attribute(), and.resolve_element()ofNsReader. Use.resolver().<...>methods instead. - #938: Now
BytesText::xml_content,BytesCData::xml_contentandBytesRef::xml_contentacceptsXmlVersionparameter to apply correct EOL normalization rules. - #944:
read_text()now returnsBytesTextwhich 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
Release notes
Open source →MSRV bumped to 1.79.
Now
quick-xmlsupports UTF-16 encoded documents. See the newDecodingReadertype.New Features
-
#956: Add
DecodingReader, aBufReadadapter that auto-detects encoding from BOM or XML declaration and transcodes to UTF-8. Enabled by theencodingfeature. -
#938: Add new enumeration
XmlVersionand typified getterBytesDecl::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
Deserializerwhen parse XML 1.0 documents. Previously XML 1.1. rules was applied.
Misc Changes
- #914: Remove deprecated
.prefixes(),.resolve(),.resolve_attribute(), and.resolve_element()ofNsReader. Use.resolver().<...>methods instead. - #938: Now
BytesText::xml_content,BytesCData::xml_contentandBytesRef::xml_contentacceptsXmlVersionparameter to apply correct EOL normalization rules. - #944:
read_text()now returnsBytesTextwhich 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)
-
-
0.39.408 May 2026Release notes
Open source →Bug Fixes
- #957: Fix slice-index panic when reading malformed DTD whose unknown markup is split across
BufReaderchunks. As with #950, the returnedEvent::DocTypemay 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
Release notes
Open source →Bug Fixes
- #957: Fix slice-index panic when reading malformed DTD whose unknown markup
is split across
BufReaderchunks. As with #950, the returnedEvent::DocTypemay 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.
- #957: Fix slice-index panic when reading malformed DTD whose unknown markup is split across
-
0.39.304 May 2026Release notes
Open source →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::DocTypemay contain the malformed DTD.
Full Changelog: v0.39.2...v0.39.3
Release notes
Open source →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::DocTypemay contain the malformed DTD.
- #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
-
0.39.220 Feb 2026Release notes
Open source →What's Changed
New Features
- #483: Implement
read_text_into()andread_text_into_async().
Bug Fixes
- #939: Fix parsing error of the tag from buffered reader, when the first byte
<is the last in theBufReadinternal buffer. This is the regression from #936.
Full Changelog: v0.39.1...v0.39.2
Release notes
Open source → - #483: Implement
-
0.39.115 Feb 2026Release notes
Open source →New Features
- #598: Add method
NamespaceResolver::set_levelwhich may be helpful in some circumstances.
Bug Fixes
- #597: Fix incorrect processing of namespace scopes in
NsReader::read_to_endNsReader::read_to_end_into,NsReader::read_to_end_into_asyncandNsReader::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 readingTextorGeneralRefevent.
- #598: Add method
-
0.39.011 Jan 2026Release notes
Open source →What's Changed
Added a way to configure
Writer. Now all configuration is contained in thewriter::Config
struct and can be applied at once. Whenserde-typesfeature is enabled, configuration is serializable.New Features
- #846: Add methods
config()andconfig_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 toexpand_empty_elements()inSerializer. - #929: Allow to pass list of field names to
impl_deserialize_for_internally_tagged_enum!macro which is required if you enum variants contains$valuefields.
Bug Fixes
- #923: Implement correct skipping of well-formed DTD.
Misc Changes
- #908: Increase minimal supported
serdeversion from 1.0.139 to 1.0.180. - #913: Deprecate
.prefixes(),.resolve(),.resolve_attribute(), and.resolve_element()ofNsReader. Use.resolver().bindings()and.resolver().resolve()methods instead. - #913:
Attributes::has_nilnow acceptsNamespaceResolverinstead ofReader<R>. - #924: (breaking change) Split
SyntaxError::UnclosedPIOrXmlDeclintoUnclosedPIandUnclosedXmlDeclfor more precise error reporting. - #924: (breaking change)
Parser::eof_errornow takes&selfand content&[u8]parameters. - #926: (breaking change) Split
SyntaxError::UnclosedTagintoUnclosedTag,
UnclosedSingleQuotedAttributeValueandUnclosedDoubleQuotedAttributeValuefor more precise error reporting.
New Contributors
- @rzmk made their first contribution in #920
- @zrneely made their first contribution in #922
- @SuchAFuriousDeath made their first contribution in #924
- @tayu0110 made their first contribution in #925
Full Changelog: v0.38.4...v0.39.0
Release notes
Open source →Added a way to configure
Writer. Now all configuration is contained in thewriter::Configstruct and can be applied at once. Whenserde-typesfeature is enabled, configuration is serializable.New Features
- #846: Add methods
config()andconfig_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 toexpand_empty_elements()inSerializer. - #929: Allow to pass list of field names to
impl_deserialize_for_internally_tagged_enum!macro which is required if you enum variants contains$valuefields.
Bug Fixes
- #923: Implement correct skipping of well-formed DTD.
Misc Changes
- #908: Increase minimal supported
serdeversion from 1.0.139 to 1.0.180. - #913: Deprecate
.prefixes(),.resolve(),.resolve_attribute(), and.resolve_element()ofNsReader. Use.resolver().bindings()and.resolver().resolve()methods instead. - #913:
Attributes::has_nilnow acceptsNamespaceResolverinstead ofReader<R>. - #924: (breaking change) Split
SyntaxError::UnclosedPIOrXmlDeclintoUnclosedPIandUnclosedXmlDeclfor more precise error reporting. - #924: (breaking change)
Parser::eof_errornow takes&selfand content&[u8]parameters. - #926: (breaking change) Split
SyntaxError::UnclosedTagintoUnclosedTag,UnclosedSingleQuotedAttributeValueandUnclosedDoubleQuotedAttributeValuefor more precise error reporting.
- #846: Add methods
-
0.38.411 Nov 2025Release notes
Open source →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 newSerializer::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
New Contributors
- @Ninja3047 made their first contribution in #904
- @alexanderkjall made their first contribution in #901
Full Changelog: v0.38.3...v0.38.4
Release notes
Open source →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 newSerializer::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
- #353: Add ability to serialize textual content as CDATA sections in
-
0.38.324 Aug 2025Release notes
Open source →Bug Fixes
- #895: Fix incorrect normalization of
\rXEOL sequences whereXis a char which is UTF-8 encoded as [c2 xx], except [c2 85].
Misc Changes
- #895: Add new
xml10_content()andxml11_content()methods which behaves the same ashtml_content()andxml_content()methods, but express intention more clearly.
- #895: Fix incorrect normalization of
-
0.38.219 Aug 2025Release notes
Open source →New Features
- #893: Implement
FusedIteratorforNamespaceBindingsIter. - #893: Make
NamespaceResolverpublic. - #893: Add
NsReader::resolver()for access to namespace resolver.
Misc Changes
- #893: Rename
PrefixItertoNamespaceBindingsIter.
- #893: Implement
-
0.38.104 Aug 2025Release notes
Open source →Important changes
To get text in events according to the XML specification (normalized EOLs) use the new methods
xml_content()instead ofdecode().Deserializeruses new method automatically.New Features
- #882: Add new methods to create
Deserializerfrom existingNsReader:Deserializer::borrowingDeserializer::borrowing_with_resolverDeserializer::bufferingDeserializer::buffering_with_resolver
- #878: Add ability to serialize structs in
$valuefields. The struct name will be used as a tag name. Previously only enums was allowed there. - #806: Add
BytesText::xml_content,BytesCData::xml_contentandBytesRef::xml_contentmethods which returns XML EOL normalized strings. - #806: Add
BytesText::html_content,BytesCData::html_contentandBytesRef::html_contentmethods which returns HTML EOL normalized strings.
Bug Fixes
- #882: Add new methods to create
-
0.38.028 Jun 2025Release notes
Open source →Significant changes
Now references to entities (as predefined, such as
<, as user-defined) reported as a newEvent::GeneralRef. Caller can parse the content of the entity and stream events from it as it is required by the XML specification. See the updatedcustom_entitiesexample!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)andAttributes::into_deserializer()whenserializefeature is enabled. This will allow do deserialize serde types right from attributes. Both methods returns the same type which implements serde'sDeserializerandMapAccesstraits. - #766: Allow to parse resolved entities as XML fragments and stream events from them.
- #766: Added new event
Event::GeneralRefwith content of general entity. - #766: Added new configuration option
allow_dangling_ampwhich allows to have a¬ followed by;in the textual data which is required for some applications for compatibility reasons. - #285: Add ability to
quick_xml::de::Textto access text with trimmed spaces
Bug Fixes
- #868: Allow to have both
$textand$valuespecial fields in one struct. Previously any text will be recognized as$valuefield even when$textfield is also presented. - #868: Skip text events when deserialize a sequence of items overlapped with text (including CDATA).
- #841: Do not strip
xmlprefix from the attributes when map them to struct fields inDeserializer.
Misc Changes
- #863: Remove
From<QName<'a>> for BytesStart<'a>because nowBytesStartstores the encoding in which its data is encoded, butQNameis a simple wrapper around byte slice. - #766:
BytesText::unescapeandBytesText::unescape_withreplaced byBytesText::decode. Now Text events does not contain escaped parts which are reported asEvent::GeneralRef.
- #863: Add
-
0.37.527 Apr 2025 -
0.37.401 Apr 2025Release notes
Open source →Misc Changes
- #852: Add
Debugimpl forNsReaderandReaderandCloneimpl forNsReader
- #852: Add
-
0.37.325 Mar 2025 -
0.37.229 Dec 2024Release notes
Open source →New Features
- #836: Add
se::to_utf8_io_writer()helper compatible withstd::io::Writeand restricted to UTF-8 encoding.
- #836: Add
-
0.37.117 Nov 2024Release notes
Open source →New Features
- #831: Add
BytesCData::escaped()fn to construct CDATA events from arbitrary user input.
- #831: Add
-
0.37.027 Oct 2024Release notes
Open source →New Features
- #826: Implement
From<String>andFrom<Cow<str>>forquick_xml::de::Text. - #826: Make
SimpleTypeDeserializerandSimpleTypeSerializerpublic. - #826: Implement
IntoDeserializerfor&mut Deserializer.
Bug Fixes
- #655: Do not write indent before and after
$textfields and those$valuefields that are serialized as a text (for example,usizeorString). - #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:boolXML content true"True","TRUE","t","Yes","YES","yes","y"false"False","FALSE","f","No","NO","no","n"
Misc Changes
- #227: Split
SeErrorfromDeErrorin theserializefeature. Serialize functions and methods now returnSeError. - #810: Return
std::io::ErrorfromWritermethods. - #811: Split
NamespaceErrorandEncodingErrorfromError. - #811: Renamed
Error::EscapeErrortoError::Escapeto match other variants. - #811: Narrow down error return type from
Errorwhere only one variant is ever returned: attribute related methods onBytesStartandBytesDeclreturnsAttrError - #820: Classify output of the
Serializerby returning an enumeration with kind of written data - #823: Do not allow serialization of consequent primitives, for example
Vec<usize>orVec<String>in$valuefields. They cannot be deserialized back with the same result - #827: Make
escapeand it variants take aimpl Into<Cow<str>>argument and implementFrom<(&'a str, Cow<'a, str>)>onAttribute - #826: Removed
DeError::InvalidInt,DeError::InvalidFloatandDeError::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
- #826: Implement
-
0.36.220 Sep 2024Release notes
Open source →Bug Fixes
- #533: Fix incorrect DocType closing bracket detection when parsing with buffered reader
-
0.36.123 Jul 2024Release notes
Open source →New Features
- #623: Added
Reader::stream()that can be used to read arbitrary data from the inner reader while track position for XML reader.
- #623: Added
-
0.36.008 Jul 2024Release notes
Open source →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
- #781: Fix conditions to start CDATA section. Only uppercase
-
0.35.029 Jun 2024Release notes
Open source →New Features
- #772: Add
reader::Config::allow_unmatched_endsto permit dangling end tags
Bug Fixes
- #773: Fixed reporting incorrect end position in
Reader::read_to_endfamily of methods and trimming of the trailing spaces inReader::read_textwhentrim_text_startis set and the last event is not aTextevent. - #771: Character references now allow any number of leading zeroes as it should.
As a result, the following variants of
quick_xml::escape::EscapeErrorare removed:TooLongDecimalTooLongHexadecimal
- #771: Fixed
Attribute::unescape_valuewhich does not unescape predefined values since 0.32.0. - #774: Fixed regression since 0.33.0:
Textevent may be skipped inread_event_into()andread_event_into_async()in some circumstances.
Misc Changes
- #771:
EscapeError::UnrecognizedSymbolrenamed toEscapeError::UnrecognizedEntity. - #771: Implemented
PartialEqforEscapeError. - #771: Replace the following variants of
EscapeErrorbyInvalidCharRefvariant with a newParseCharRefErrorinside:EntityWithNullInvalidDecimalInvalidHexadecimalInvalidCodepoint
- #772: Add
-
0.34.024 Jun 2024Release notes
Open source →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_valueandAttribute::decode_and_unescape_value_withnow acceptsDecoderinstead ofReader. UseReader::decoder()to get it. - #760:
Writer::write_eventnow consumes event. UseEvent::borrow()if you want to keep ownership. - #751: Type of
Reader::error_position()andReader::buffer_position()changed fromusizetou64. - #751: Type alias
Spanchanged fromRange<usize>toRange<u64>.
- #751: Fix internal overflow when read 4GB+ files on 32-bit targets using
-
0.33.021 Jun 2024Release notes
Open source →New Features
- #758: Implemented
From<QName>forBytesStartandBytesEnd.
Bug Fixes
- #755: Fix incorrect missing of trimming all-space text events when
trim_text_start = falseandtrim_text_end = true.
Misc Changes
- #650: Change the type of
Event::PIto a new dedicatedBytesPItype. - #759: Make
constas 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_entityunderescape-htmlfeature again. This function has significant influence to the compilation time (10+ seconds or 5x times)
- #758: Implemented
-
0.32.010 Jun 2024Release notes
Open source →The way to configure parser is changed. Now all configuration is contained in the
Configstruct and can be applied at once. Whenserde-typesfeature 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. ForSyntaxErrors the rangeerror_position()..buffer_position()also will represent a span of error.The way of resolve entities with
unescape_withare changed. Those methods no longer resolve predefined entities.New Features
- #513: Allow to continue parsing after getting new
Error::IllFormed. - #677: Added methods
config()andconfig_mut()to inspect and change the parser configuration. Previous builder methods onReader/NsReaderwas replaced by direct access to fields of config usingreader.config_mut().<...>. - #684: Added a method
Config::enable_all_checksto 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_enummacro 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_entityquick_xml::escape::resolve_xml_entityquick_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_elementsis 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::Errortype to provide more accurate information:Error::EndEventMismatchreplaced byIllFormedError::MismatchedEndTagin some casesError::EndEventMismatchreplaced byIllFormedError::UnmatchedEndTagin some casesError::TextNotFoundwas removed because not usedError::UnexpectedBangreplaced bySyntaxErrorError::UnexpectedEofreplaced bySyntaxErrorin some casesError::UnexpectedEofreplaced byIllFormedErrorin some casesError::UnexpectedTokenreplaced byIllFormedError::DoubleHyphenInCommentError::XmlDeclWithoutVersionreplaced byIllFormedError::MissingDeclVersion(in #684)Error::EmptyDocTypereplaced byIllFormedError::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. Useerror_position()for that. - #684: Now
<??>parsed asEvent::PIwith empty content instead of raising syntax error. - #684: Now
<?xml?>parsed asEvent::Declinstead ofEvent::PI. - #362: Now default quote level is
QuoteLevel::Partialwhen using serde serializer. - #689:
buffer_position()now always report the position the parser last seen. To get an error position useerror_position(). - #738: Add an example of how to deserialize XML elements into Rust enums using an intermediate custom deserializer.
- #748: Implement
CloneforDeEvent,PayloadEventandText. - #734: Rename
NoEntityResolvertoPredefinedEntityResolver. - #734: No longer resolve predefined entities (
lt,gt,apos,quot,amp) inunescape_withfamily of methods. You should do that by yourself using the methods listed above.
- #513: Allow to continue parsing after getting new
-
0.31.023 Oct 2023Release notes
Open source →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 (
xmlandxmlns) to their appropriate URIs. Also, enforce namespace constraints related to these well-known namespaces. - #635: Add support for async
ElementWriteroperations.
Bug Fixes
- #660: Fixed incorrect deserialization of
xs:lists from empty tags (<tag/>or<tag></tag>). Previously anDeError::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 after123up 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) intoOptionfields: now they are always deserialized asSome("").
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
Errorvariant --Error::InvalidPrefixBind. - #651: Relax requirement for version of
arbitrarydependency -- 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 addedElementWriter::write_inner_content_asyncof 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
- #545: Resolve well-known namespaces (
-
0.30.023 Jul 2023Release notes
Open source →New Features
- #609: Added
Writer::write_serializableto provide the capability to serialize arbitrary types using serde when using the lower-levelWriterAPI. - #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 usingread_event_into*functions.
Misc Changes
- #609: Added
-
0.29.012 Jun 2023Release notes
Open source →New Features
- #601: Add
serde_helpermodule 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
AsyncWritetrait 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::EmptyDocTypeon 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.
- #601: Add
-
0.28.212 Apr 2023Release notes
Open source →New Features
- #581: Allow
Deserializerto setquick_xml::de::EntityResolverfor resolving unknown entities that would otherwise cause the parser to return an [EscapeError::UnrecognizedSymbol] error.
Misc Changes
- #581: Allow
-
0.28.119 Mar 2023Release notes
Open source →Misc Changes
- #579:
ElementWriter.write_inner_contentnow uses aFnOnceinstead of a more restrictiveFnclosure
- #579:
-
0.28.013 Mar 2023Release notes
Open source →New Features
- #541: (De)serialize specially named
$textenum variant in externally tagged enums to / from textual content - #556:
to_writerandto_stringnow accept?Sizedtypes - #556: Add new
to_writer_with_rootandto_string_with_roothelper functions - #520: Add methods
BytesText::inplace_trim_startandBytesText::inplace_trim_endto trim leading and trailing spaces from text events - #565: Allow deserialize special field names
$valueand$textinto borrowed fields when use serde deserializer - #568: Rename
Writer::innerintoWriter::get_mut - #568: Add method
Writer::get_ref - #569: Rewrite the
Reader::read_event_into_asyncas an async fn, making the futureSendif possible. - #571: Borrow element names (
<element>) when deserialize with serde. This change allow to deserialize intoHashMap<&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 whereTis some sequence type (for example,Vecor tuple) - #540: Fix a compilation error (probably a rustc bug) in some circumstances.
Serializer::newandSerializer::with_rootnow accepts only references toWriter. - #520: Merge consequent (delimited only by comments and processing instructions)
texts and CDATA when deserialize using serde deserializer.
DeEvent::TextandDeEvent::CDataevents was replaced byDeEvent::Textwith merged content. The same behavior for theReaderdoes 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
- #541: (De)serialize specially named
-
0.27.128 Dec 2022 -
0.27.025 Dec 2022Release notes
Open source →New Features
- #521: Implement
Clonefor all error types. This required changingError::Ioto containArc<std::io::Error>instead ofstd::io::Errorsincestd::io::Errordoes not implementClone.
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::EndEventMismatchafter disabling and enabling.check_end_names - #517: Fix swapped codes for
\rand\ncharacters 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
derivefeature to get quick-xml'sserializefeature foredition = 2021orresolver = 2crates
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
$valuespecial name for a field a new$textspecial name was added:$textis used if you want to map field to text content only. No markup is expected (but text can represent a list as defined byxs:listtype)$valueis used if you want to map elements with different names to one field, that should be represented either by anenum, or by sequence ofenums (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:
serdefeature that used to make some types serializable, renamed toserde-types -
#528: Added documentation for XML to
serdemapping
- #521: Implement
-
0.26.023 Oct 2022 -
0.25.010 Sep 2022Release notes
Open source →Bug Fixes
- #469: Fix incorrect parsing of CDATA and comments when using buffered readers
Misc Changes
-
0.24.110 Sep 2022Release notes
Open source →Bug Fixes
- #469: Fix incorrect parsing of CDATA and comments when using buffered readers
-
0.24.028 Aug 2022 withdrawnRelease notes
Open source →New Features
- #387: Allow overlapping between elements of sequence and other elements
(using new feature
overlapped-lists) - #393: New module
namewithQName,LocalName,Namespace,PrefixandPrefixDeclarationwrappers around byte arrays andResolveResultwith the result of namespace resolution - #180: Make
Decoderstruct public. You already had access to it via theReader::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_strnow 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 ReaderNew function in NsReaderread_event-- borrow from inputread_resolved_event-- borrow from inputread_event_intoread_namespaced_eventread_resolved_event_intoresolveevent_namespaceresolve_elementattribute_namespaceresolve_attribute - #439: Added utilities
detect_encoding()anddecode()under thequick-xml::encodingnamespace. - #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_textmethod 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::keyAttr::valueAttributes::htmlAttributes::newBytesDecl::from_startDecoder::encodingLocalName::into_innerNamespace::into_innerPrefix::into_innerQName::into_innerReader::buffer_positionReader::decoderReader::get_refSerializer::newSerializer::with_rootWriter::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
$valuefield - #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 theserializefeature enabled - #393: Now
event_namespace,attribute_namespaceandread_event_namespacedreturnsResolveResult::Unknownif 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::Textevents - #412: Fix using incorrect encoding if
read_to_endfamily of methods orread_textmethod 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
Textevent (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::TextRemoved because never raised DeError::InvalidEnumRemoved because never raised DeError::XmlRenamed to DeError::InvalidXmlfor consistency withDeError::InvalidBooleanDeError::IntRenamed to DeError::InvalidIntfor consistency withDeError::InvalidBooleanDeError::FloatRenamed to DeError::InvalidFloatfor consistency withDeError::InvalidBooleanDeError::StartRenamed to DeError::UnexpectedStartand tag name added to an errorDeError::EndRenamed to DeError::UnexpectedEndand tag name added to an errorDeEvent::EofRenamed to DeError::UnexpectedEofDeError::EndOfAttributesRenamed to DeError::KeyNotFoundDeError::ExpectedStartAdded -
#391: Added code coverage
-
#393:
event_namespaceandattribute_namespacenow acceptQNameand returnsResolveResultandLocalName,read_event_namespacednow returnsResolveResultinstead ofOption<[u8]> -
#393: Types of
Attribute::keyandAttr::key()changed toQName -
#393: Now
BytesStart::name()andBytesEnd::name()returnsQName, andBytesStart::local_name()andBytesEnd::local_name()returnsLocalName -
#191: Remove unused
reader.decoder().decode_owned(). If you ever used it, useString::from_utf8instead (which that function did) -
#191: Remove
*_without_bommethods from theAttributesstruct because they are useless. Use the same-named methods without that suffix instead. Attribute values cannot contain BOM -
#191: Remove
Reader::decode()andReader::decode_without_bom(), they are replaced byDecoder::decode()and nothing. Usereader.decoder().decode_*(...)instead ofreader.decode_*(...)for now.Reader::encoding()is replaced byDecoder::encoding()as well -
#180: Eliminated the differences in the decoding API when feature
encodingenabled 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
encodingfeature was enabled, decoding functions would returnResult<Cow<&str>>while without this feature they would returnResult<&str>. With this change, onlyResult<Cow<&str>>is returned regardless of the status of the feature. -
#180: Error variant
Error::Utf8replaced byError::NonDecodable -
#118: Remove
BytesStart::unescaped*set of methods because they could return wrong results Use methods onAttributeinstead -
#403: Remove deprecated
quick_xml::de::from_bytesandDeserializer::from_borrowing_reader -
#412: Rename methods of
Reader:Old Name New Name read_eventread_event_intoread_to_endread_to_end_intoread_textread_text_intoread_event_unbufferedread_eventread_to_end_unbufferedread_to_end -
#412: Change
read_to_end*andread_text_intoto acceptQNameinstead ofAsRef<[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*_withBytesText::unescaped()BytesText::unescape()Attribute::unescaped_*Attribute::unescape_* -
#329: Also, that functions now borrow from the input instead of event / attribute
-
#416:
BytesStart::to_borrowedrenamed toBytesStart::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_plainbecause it internally did escaping of a byte array, but since now escaping works on strings. UseBytesText::newinstead -
#428: Removed
BytesText::escaped(). Use.as_ref()provided byDerefimpl 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
Attributesconstructors to accept a&strslices instead of&[u8]slices. Handmade events has always been assumed to store their content UTF-8 encoded. -
#428: Removed
Decoderparameter from_and_decodeversions of functions forBytesText(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_sliceandquick_xml::de::from_slicemethods because deserializing from a byte array cannot guarantee borrowing due to possible copying while decoding. -
#455: Removed
Reader::read_text_intowhich is just a thin wrapper over match onEvent::Text -
#456: Reader and writer stuff grouped under
readerandwritermodules. 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, useWriter::write_bom(). -
#467: Removed
Deserializer::newbecause 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_implto 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/documentsare 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
- #387: Allow overlapping between elements of sequence and other elements
(using new feature
-
0.23.110 Sep 2022Release notes
Open source →Bug Fixes
- #469: Fix incorrect parsing of CDATA and comments when using buffered readers
-
0.23.025 May 2022 withdrawnRelease notes
Open source →- feat: add support for
i128/u128in 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_sliceandDeserializer::from_reader - refactor: deprecate
from_bytesandDeserializer::from_borrowing_readerbecause they are fully equivalent tofrom_sliceandDeserializer::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::InvalidUnitvariant 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::UnexpectedBangnow 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
BytesCDatatype (quick-xml#311) - feat: add
Reader::get_ref()andReader::get_mut(), renameReader::into_underlying_reader()toReader::into_inner() - refactor: now
Attributes::next()returns a new typeAttrErrorwhen 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()orhtml_attributes()(#4)
- feat: add support for
-
0.23.0-alpha321 Aug 2021 pre-releaseRelease notes
Open source →- fix: use element name (with namespace) when unflattening (serialize feature)
-
0.23.0-alpha214 Aug 2021 pre-release -
0.23.0-alpha110 Aug 2021 pre-releaseRelease notes
Open source →- 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
-
0.22.023 Feb 2021Release notes
Open source →- 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_entitiesversions of all `unescape_*\ methods - test: more robust test for numeric entities
- refactor: add explicit pre-condition about custom_entities
- feat (breaking): Move html entity escape behind a
-
0.21.003 Feb 2021Release notes
Open source →- feat: Split text trim into start and end
- fix:
$valuerename 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
-
0.20.017 Oct 2020Release notes
Open source →- 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()andto_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:
unitdeserialization and newtype and struct deserialization in adjacently tagged enums
-
0.19.026 Sep 2020Release notes
Open source →- docs: Add example for nested parsing
- fix:
buffer_positionnot 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_allinstead ofwrite - fix: (Serde) Serialize basic types as attributes (breaking change)
- test: Fix benchmarks on Windows and add trimmed variant
- feat: deserialize bytes
-
0.18.115 Mar 2020Nothing published for this version
-
0.18.015 Mar 2020Release notes
Open source →- feat: add
decode_without_bomfns for BOM prefixed text fields - fix: decode then unescape instead of unescape and decode
- feat: add
-
0.17.217 Dec 2019 -
0.17.111 Dec 2019 -
0.17.011 Oct 2019Release notes
Open source →- perf: speed up (un)escape a little
- feat: remove failure completely (breaking change) and implement
std::error::ErrorforError - feat: improve
Debugs forAttribute,BytesStart,BytesEnd,BytesText
-
0.16.102 Sep 2019Release notes
Open source →- refactor: remove derive_more dependency (used only in 2 structs)
- refactor: move xml-rs bench dependency into another local crate
-
0.16.024 Aug 2019Release notes
Open source →- feat: (breaking change) set failure and encoding_rs crates as optional.
You should now use respectively
use-failureandencodingfeatures to get the old behavior - perf: improve perf using memchr3 iterator. Reading is 18% better on benches
- feat: (breaking change) set failure and encoding_rs crates as optional.
You should now use respectively
-
0.15.015 Jul 2019 -
0.14.008 Apr 2019Release notes
Open source →- feat: make failure error crate optional. To revert back to old behavior, use the
--failurefeature.
- feat: make failure error crate optional. To revert back to old behavior, use the
-
0.13.320 Feb 2019Release notes
Open source →- feat: allow changing name without deallocating
BytesStartbuffer - feat: add standard error type conversion
- feat: allow changing name without deallocating
-
0.13.212 Jan 2019 -
0.13.123 Oct 2018