NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #293 most downloaded on crates.io
High performance xml reader and writer
Last release 1 months ago
22 Aug 2026
Ships fairly regularly
a new release about every 6 weeks
Nearly every release is documented
notes for 59 of the last 60 stable releases
4 versions withdrawn
withdrawn after publishing
11 years old
104 releases · first in 2016
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
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.
Reader::from_reader() without DecodingReader will nowError::Encoding instead of silently passing through invalid bytes.DecodingReader to transcode non-UTF-8 sources.QName, LocalName, Prefix, Namespace, PrefixDeclaration)&str instead of &[u8]. into_inner() returns &str, and AsRef<str>AsRef<[u8]> has been removed). ResolveResult::Unknown now contains StringVec<u8>, and NamespaceError variants contain String instead of Vec<u8>.decoder: Decoder field from event types (BytesStart, BytesText,BytesCData, BytesRef) and Attributes. The decoder() method is no longer availableError::missed_end() no longer takes a Decoder parameter.BytesStart, BytesEnd, BytesText, BytesCData, BytesPI,BytesRef) now store Cow<str> internally instead of Cow<[u8]>. into_inner() onBytesText, BytesCData, BytesPI, and BytesRef now returns Cow<str>.BytesStart::set_name() now takes &str instead of &[u8].Event enum now implement Deref<Target = str>Deref<Target = [u8]>. Explicit AsRef<str> impls are provided todecode() methods from BytesText, BytesCData, and BytesRef.&str via Deref. The xml10_content(),xml11_content(), xml_content(), and html_content() methods now returnCow<str> directly instead of Result<Cow<str>, EncodingError>.Attribute::value is now Cow<'a, str> instead of Cow<'a, [u8]>.From<(&[u8], &[u8])> impl has been removed.BytesDecl::version(), encoding(), and standalone() now returnCow<'_, str> instead of Cow<'_, [u8]>.Reader::decoder() method. Use Reader::encoding() insteadencoding feature). Removed decoder() from the XmlReadDecoder (the struct is kept only forAttribute methods).NamespaceError::TooManyDeclarations has been renamed to TooManyBindings,NamespaceResolver::set_max_declarations_per_element has been renamed toNamespaceResolver::set_max_namespace_bindings, and the semantic behavior hasDeError::UnexpectedStart renamed to DeError::MixedContent. That errorfield from<field>text <tag/> another text</field>.\r, \n, and \t in attribute values , , and 	 respectively, preventing silent data loss fromAttribute::fromDeserializer now correctly handles namespaces. PreviouslyAttributes::new and Attributes::html now return empty iterators whenNamespaceResolver::push (and hence every NsReader Start/EmptyNamespaceError::TooDeeplyNested when a documentu16::MAX, instead of overflowing the internalu16 depth counter. Previously the unguarded nesting_level += 1 panickedoverflow-checks builds and silently wrapped in release, corruptingNamespaceResolver now caps the total number of in-scope namespaceset_max_namespace_bindings),max_declarations_per_element limit.Deserializer now enforces a configurable recursion-depthserde_json). Deeply nested XML returnsDeError::TooDeeplyNested instead of overflowing the native call stack.Deserializer::recursion_limit() to adjust.\r in text content is now escaped as by the serde serializer,BytesText::new(), escape(), partial_escape(), and minimal_escape(),\n from XML end-of-line normalization on\r cannot be preserved through CDATA serializationgetting_started, writer,serde_roundtrip, reader_patterns, visitor) and an examples/README.mdAttribute methods that take a Decoder parameter, sincedecoded_and_normalized_value(),decoded_and_normalized_value_with(), decode_and_unescape_value(), anddecode_and_unescape_value_with(). Use normalized_value() andnormalized_value_with() instead.NamespaceResolver::with that allows temporary applying namespaceDeserializer::resolver and Deserializer::resolver_mut methodsNsReader internally.Hash, PartialOrd, and Ord for BytesText and BytesCData types.Full Changelog: v0.41.0...v0.42.0
One column per quarter.
@qifan-sailboat made their first contribution in #972
NsReader::resolver_mut() and NamespaceResolver::{max_declarations_per_element, set_max_declarations_per_element}.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.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).Full Changelog: v0.40.1...v0.41.0
@williamareynolds made their first contribution in #964
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.Full Changelog: v0.40.0...v0.40.1
which ought to be used in place of deprecated
MSRV bumped to 1.79.
Now quick-xml supports the UTF-16 and ISO-2022-JP encoded documents. See the new DecodingReader type.
#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.
Deserializer when parse XML 1.0 documents. Previously XML 1.1. rules was applied..prefixes(), .resolve(), .resolve_attribute(), and .resolve_element() of NsReader. Use .resolver().<...> methods instead.BytesText::xml_content, BytesCData::xml_content and BytesRef::xml_content accepts XmlVersion parameter to apply correct EOL normalization rules.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()?.Full Changelog: v0.39.4...v0.40.0
Bug Fixes #957 : Fix slice-index panic when reading malformed DTD whose unknown markup is split across BufReader chunks. As with #950 , the returned E
BufReader chunks. As with #950, the returned Event::DocType may contain the malformed DTD; this fix only ensures that the parser does not panic.< 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
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 th
Event::DocType may contain the malformed DTD.Full Changelog: v0.39.2...v0.39.3
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
read_text_into() and read_text_into_async().< is the last in the BufRead internal buffer. This is the regression from #936.Full Changelog: v0.39.1...v0.39.2
[#598]: Add method NamespaceResolver::set_level which may be helpful in some circumstances.
NamespaceResolver::set_level which may be helpful in some circumstances.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..read_text() when it is called after reading Text or GeneralRef event.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
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.
config() and config_mut() to inspect and change the writer configuration./> in self-closed tags for maximum compatibility with XHTML.empty_element_handling() as a more powerful alternative to expand_empty_elements() in Serializer.impl_deserialize_for_internally_tagged_enum! macro which is required if you enum variants contains $value fields.serde version from 1.0.139 to 1.0.180..prefixes(), .resolve(), .resolve_attribute(), and .resolve_element() of NsReader. Use .resolver().bindings() and .resolver().resolve() methods instead.Attributes::has_nil now accepts NamespaceResolver instead of Reader<R>.SyntaxError::UnclosedPIOrXmlDecl into UnclosedPI and UnclosedXmlDecl for more precise error reporting.Parser::eof_error now takes &self and content &[u8] parameters.SyntaxError::UnclosedTag into UnclosedTag,UnclosedSingleQuotedAttributeValue and UnclosedDoubleQuotedAttributeValue for more precise error reporting.Full Changelog: v0.38.4...v0.39.0
@Ninja3047 made their first contribution in #904
Serializer. Everywhere where the text node may be created, a CDATA section(s) could be produced instead. See the new Serializer::text_format() method.<int> 42 </int>. That space characters are usually indent added during serialization and other XML serialization libraries trims themFull Changelog: v0.38.3...v0.38.4
[#895]: Fix incorrect normalization of \rX EOL sequences where X is a char which is UTF-8 encoded as [c2 xx], except [c2 85].
\rX EOL sequences where X is a char which is
UTF-8 encoded as [c2 xx], except [c2 85].xml10_content() and xml11_content() methods which behaves the same as
html_content() and xml_content() methods, but express intention more clearly.[#893]: Implement FusedIterator for NamespaceBindingsIter.
To get text in events according to the XML specification (normalized EOLs) use the new methods xml_content() instead of decode(). Deserializer uses ne
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.
Deserializer from existing NsReader:
Deserializer::borrowingDeserializer::borrowing_with_resolverDeserializer::bufferingDeserializer::buffering_with_resolver$value fields. The struct name will
be used as a tag name. Previously only enums was allowed there.BytesText::xml_content, BytesCData::xml_content and BytesRef::xml_content
methods which returns XML EOL normalized strings.BytesText::html_content, BytesCData::html_content and BytesRef::html_content
methods which returns HTML EOL normalized strings.Now references to entities (as predefined, such as <, as user-defined) reported as a new Event::GeneralRef. Caller can parse the content of the entity
Now references to entities (as predefined, such as <, 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.
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.Event::GeneralRef with content of general entity.allow_dangling_amp which allows to have
a & not followed by ; in the textual data which is required for some applications
for compatibility reasons.quick_xml::de::Text to access text with trimmed spaces$text and $value special fields in one struct. Previously
any text will be recognized as $value field even when $text field is also presented.xml prefix from the attributes when map them to struct fields in Deserializer.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.BytesText::unescape and BytesText::unescape_with replaced by BytesText::decode.
Now Text events does not contain escaped parts which are reported as Event::GeneralRef.[#857]: Add BytesCData::decode().
BytesCData::decode().[#852]: Add Debug impl for NsReader and Reader and Clone impl for NsReader
Debug impl for NsReader and Reader and Clone impl for NsReader[#850]: Add Attribute::as_bool() method to get an attribute value as a boolean.
[#836]: Add se::to_utf8_io_writer() helper compatible with std::Write and restricted to UTF-8 encoding.
se::to_utf8_io_writer() helper compatible with std::io::Write and restricted to UTF-8 encoding.[#831]: Add BytesCData::escaped() fn to construct CDATA events from arbitrary user input.
BytesCData::escaped() fn to construct CDATA events from arbitrary user input.[#826]: Implement From and From > for quick_xml::Text.
From<String> and From<Cow<str>> for quick_xml::de::Text.SimpleTypeDeserializer and SimpleTypeSerializer public.IntoDeserializer for &mut Deserializer.$text fields and those $value fields
that are serialized as a text (for example, usize or String)."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" |
SeError from DeError in the serialize feature.
Serialize functions and methods now return SeError.std::io::Error from Writer methods.NamespaceError and EncodingError from Error.Error::EscapeError to Error::Escape to match other variants.Error where only one variant is ever returned:
attribute related methods on BytesStart and BytesDecl returns AttrErrorSerializer by returning an enumeration with kind of written dataVec<usize> or
Vec<String> in $value fields. They cannot be deserialized back with the same resultescape and it variants take a impl Into<Cow<str>> argument and implement
From<(&'a str, Cow<'a, str>)> on AttributeDeError::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[#533]: Fix incorrect DocType closing bracket detection when parsing with buffered reader
[#623]: Added Reader::stream() that can be used to read arbitrary data from the inner reader while track position for XML reader.
Reader::stream() that can be used to read arbitrary data
from the inner reader while track position for XML reader.[#781]: Fix conditions to start CDATA section. Only uppercase <![CDATA[ can start it. Previously any case was allowed.
[#772]: Add reader::Config::allow_unmatched_ends to permit dangling end tags
reader::Config::allow_unmatched_ends to permit dangling end tagsReader::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.quick_xml::escape::EscapeError are removed:
TooLongDecimalTooLongHexadecimalAttribute::unescape_value which does not unescape predefined values since 0.32.0.Text event may be skipped in read_event_into()
and read_event_into_async() in some circumstances.EscapeError::UnrecognizedSymbol renamed to EscapeError::UnrecognizedEntity.PartialEq for EscapeError.EscapeError by InvalidCharRef variant
with a new ParseCharRefError inside:
EntityWithNullInvalidDecimalInvalidHexadecimalInvalidCodepoint[#751]: Fix internal overflow when read 4GB+ files on 32-bit targets using Reader readers.
Reader<impl BufRead> readers.Attribute::decode_and_unescape_value and Attribute::decode_and_unescape_value_with now
accepts Decoder instead of Reader. Use Reader::decoder() to get it.Writer::write_event now consumes event. Use Event::borrow() if you want to keep ownership.Reader::error_position() and Reader::buffer_position() changed from usize to u64.Span changed from Range<usize> to Range<u64>.[#758]: Implemented From for BytesStart and BytesEnd.
From<QName> for BytesStart and BytesEnd.trim_text_start = false and trim_text_end = true.Event::PI to a new dedicated BytesPI type.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()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)[#722]: Allow to pass owned strings to Writer::create_element. This is breaking change!
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.
Error::IllFormed.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().<...>.Config::enable_all_checks to turn on or off all
well-formedness checks.escape::minimal_escape() which escapes only & and <.BytesCData::minimal_escape() which escapes only & and <.Serializer::set_quote_level() which allow to set desired level of escaping.NsReader::prefixes() to list all the prefixes currently declared.impl_deserialize_for_internally_tagged_enum macro so that
it can handle every attribute that does not match existing cases within an enum variant.Writer::create_element. This is breaking change!ElementWriter::new_line() which enables pretty printing elements with multiple attributes.Deserializer::get_ref() to get XML Reader from serde Deserializerquick_xml::escape::resolve_predefined_entityquick_xml::escape::resolve_xml_entityquick_xml::escape::resolve_html5_entityquick_xml::reader::PiParser.quick_xml::reader::ElementParser.<.Error::IllFormed(DoubleHyphenInComment).Error::IllFormed(MissingDoctypeName).expand_empty_elements is set to true.quick_xml::Error type to provide more accurate information:
Error::EndEventMismatch replaced by IllFormedError::MismatchedEndTag in some casesError::EndEventMismatch replaced by IllFormedError::UnmatchedEndTag in some casesError::TextNotFound was removed because not usedError::UnexpectedBang replaced by SyntaxErrorError::UnexpectedEof replaced by SyntaxError in some casesError::UnexpectedEof replaced by IllFormedError in some casesError::UnexpectedToken replaced by IllFormedError::DoubleHyphenInCommentError::XmlDeclWithoutVersion replaced by IllFormedError::MissingDeclVersion (in #684)Error::EmptyDocType replaced by IllFormedError::MissingDoctypeName (in #684)SyntaxErrors: now they are always points
to the start of markup (i. e. to the < character) with error. Use error_position()
for that.<??> parsed as Event::PI with empty content instead of raising
syntax error.<?xml?> parsed as Event::Decl instead of Event::PI.QuoteLevel::Partial when using serde serializer.buffer_position() now always report the position the parser last seen.
To get an error position use error_position().Clone for DeEvent, PayloadEvent and Text.NoEntityResolver to PredefinedEntityResolver.lt, gt, apos, quot, amp)
in unescape_with family of methods. You should do that by yourself using the methods
listed above.MSRV bumped to 1.56! Crate now uses Rust 2021 edition.
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
xml and xmlns) to their appropriate URIs.
Also, enforce namespace constraints related to these well-known namespaces.ElementWriter operations.xs:lists from empty tags (<tag/>
or <tag></tag>). Previously an DeError::UnexpectedEof") was returned in that case<int>123<something-else/></int> is no longer valid
content. Previously all data after 123 up to closing tag would be silently skipped.simpleTypes (for example, attributes) into
Option fields: now they are always deserialized as Some("").Error variant -- Error::InvalidPrefixBind.arbitrary dependency -- we're actually
compatible with version 1.0.0 and up.ElementWriter::write_inner_content
(and newly added ElementWriter::write_inner_content_async of course).xs:lists when some elements serialized to an empty string.[#609]: Added Writer::write_serializable to provide the capability to serialize arbitrary types using serde when using the lower-level Writer API.
Writer::write_serializable to provide the capability to serialize
arbitrary types using serde when using the lower-level Writer API.<!--> when using read_event_into* functions.[#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 e
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.AsyncWrite trait implementations.DeError::ExpectedStartError::EmptyDocType on empty doctype instead
of crashing because of a debug assertion.[#581]: Allow Deserializer to set quick_xml::EntityResolver for resolving unknown entities that would otherwise cause the parser to return an [EscapeE
Deserializer to set quick_xml::de::EntityResolver for
resolving unknown entities that would otherwise cause the parser to return
an [EscapeError::UnrecognizedSymbol] error.[#579]: ElementWriter.write_inner_content now uses a FnOnce instead of a more restrictive Fn closure
ElementWriter.write_inner_content now uses a FnOnce instead of a more restrictive Fn closure[#541]: (De)serialize specially named $text enum variant in [externally tagged] enums to / from textual content
$text enum variant in externally tagged
enums to / from textual contentto_writer and to_string now accept ?Sized typesto_writer_with_root and to_string_with_root helper functionsBytesText::inplace_trim_start and BytesText::inplace_trim_end
to trim leading and trailing spaces from text events$value and $text into borrowed
fields when use serde deserializerWriter::inner into Writer::get_mutWriter::get_refReader::read_event_into_async as an async fn, making the future Send if possible.<element>) when deserialize with serde.
This change allow to deserialize into HashMap<&str, T>, for exampleAsyncWrite.xmlns:xxx) that was broken since #490Option<T> fields where T is some
sequence type (for example, Vec or tuple)Serializer::new and Serializer::with_root now accepts only references to Writer.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[#530]: Fix an infinite loop leading to unbounded memory consumption that occurs when skipping events on malformed XML with the overlapped-lists featu
[#521]: Implement Clone for all error types. This required changing Error::Io to contain Arc instead of std::Error since std::Error does not 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."42") no longer can be serialized because XML name cannot start
from a digit<?xml version="1.0" encoding="UTF-8"?>
<!-- list of enum Enum { A, B, С } -->
<A/>
<B/>
<C/>
Error::EndEventMismatch after disabling and enabling
.check_end_names\r and \n characters when escaping themunwanted text<struct>...</struct>
xs:lists with encoded spaces: they still
act as delimiters, which is confirmed also by mature XmlBeans Java libraryderive feature to get
quick-xml's serialize feature for edition = 2021 or resolver = 2 crates#490: Removed $unflatten= special prefix for fields for serde (de)serializer, because:
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 markupRefer 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
[#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
[#469]: Fix incorrect parsing of CDATA and comments when using buffered readers
[#469]: Fix incorrect parsing of CDATA and comments when using buffered readers
[#403]: Remove deprecated quick_xml::from_bytes and Deserializer::from_borrowing_reader
overlapped-lists)name with QName, LocalName, Namespace, Prefix
and PrefixDeclaration wrappers around byte arrays and ResolveResult with
the result of namespace resolutionDecoder 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 structxs:listReader::from_str / Deserializer::from_str / from_str now ignore
the XML declared encoding and always use UTF-8borrow() methods in all event structs which allows to get
a borrowed version of any eventNsReader, 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 |
detect_encoding() and decode() under the quick-xml::encoding namespace.read_to_end* methods to return a span between tagsReader::read_text method to return a raw content (including markup) between tagsWriter::write_bom() method for inserting a Byte-Order-Mark into the document.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$value fieldVec<T>), where elements of this sequence contains
another sequence. This error affects only users with the serialize feature enabledevent_namespace, attribute_namespace and read_event_namespaced
returns ResolveResult::Unknown if prefix was not registered in namespace bufferEvent::Text eventsread_to_end family of methods or read_text
method not found a corresponding end tag and reader has non-UTF-8 encodingText event (i.e. <xml>tag</xml>)
and a document encoding is not an UTF-8#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
Reader::read_event_impl to ensure that proper events generated for corresponding inputs/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
[#469]: Fix incorrect parsing of CDATA and comments when using buffered readers
refactor: deprecate from_bytes and Deserializer::from_borrowing_reader because they are fully equivalent to from_slice and Deserializer::new
i128 / u128 in attributes or text/CDATA contentunits from any data in attribute values and text nodesDeserializer::from_str, Deserializer::from_slice and Deserializer::from_readerfrom_bytes and Deserializer::from_borrowing_reader because
they are fully equivalent to from_slice and Deserializer::newunits from text and CDATA content.
DeError::InvalidUnit variant is removed, because after fix it is no longer usedElementWriter, introduced in #274
(0.23.0-alpha2) now available to end users<!doctype > definition (used in HTML 5) when parse document from &[u8]Error::UnexpectedBang now provide the byte found<root>...</root> -- one tag with content)BytesCData type
(quick-xml#311)Reader::get_ref() and Reader::get_mut(), rename
Reader::into_underlying_reader() to Reader::into_inner()Attributes::next() returns a new type AttrError when attribute parsing failed
(#4)FusedIterator (#4)attributes()
or html_attributes() (#4)fix: use element name (with namespace) when unflattening (serialize feature)
fix: failing tests with features
style: convert to rust edition 2018
Writer::write_nested_eventBytesStart::try_get_attributefeat (breaking): Move html entity escape behind a 'escape-html' feature to help with compilation
'escape-html' feature to help with compilation*_with_custom_entities versions of all `unescape_*\ methodsfeat: Split text trim into start and end
$value rename should work the same for deserialization and serializationtest: Add tests for indentation
BytesStart: to_borrowed() and to_end()unit deserialization and newtype and struct deserialization in adjacently tagged enumsfix: (Serde) Serialize basic types as attributes (breaking change)
buffer_position not properly set sometimesCloneablewrite_all instead of writeNothing published for this version
feat: add decode_without_bom fns for BOM prefixed text fields
decode_without_bom fns for BOM prefixed text fieldsdocs: update readme with example for $value
$valuefeat: add new serialize feature to support serde serialize/deserialize
serialize feature to support serde serialize/deserializefeat: remove failure completely (breaking change) and implement std::Error for Error
std::error::Error for ErrorDebugs for Attribute, BytesStart, BytesEnd, BytesTextrefactor: remove derive_more dependency (used only in 2 structs)
feat: (breaking change) set failure and encoding_rs crates as optional. You should now use respectively use-failure and encoding features to get the o…
use-failure and encoding features to get the old behavior- feat: remove Seek bound - style: rustfmt
feat: make failure error crate optional. To revert back to old behavior, use the --failure feature.
--failure feature.feat: allow changing name without deallocating BytesStart buffer
BytesStart bufferfix: allow whitespace in End events
feat: Add into_underlying_reader method for Reader
Reader<BufRead + Seek>Your coding agent can read these notes before it upgrades. Set up the MCP server →