quick_xml/lib.rs
1//! High performance XML reader/writer.
2//!
3//! # Description
4//!
5//! quick-xml contains two modes of operation:
6//!
7//! A streaming API based on the [StAX] model. This is suited for larger XML documents which
8//! cannot completely read into memory at once.
9//!
10//! The user has to explicitly _ask_ for the next XML event, similar to a database cursor.
11//! This is achieved by the following two structs:
12//!
13//! - [`Reader`]: A low level XML pull-reader where buffer allocation/clearing is left to user.
14//! - [`Writer`]: A XML writer. Can be nested with readers if you want to transform XMLs.
15//!
16//! Especially for nested XML elements, the user must keep track _where_ (how deep)
17//! in the XML document the current event is located.
18//!
19//! quick-xml contains optional support of asynchronous reading and writing using [tokio].
20//! To get it enable the [`async-tokio`](#async-tokio) feature.
21//!
22//! Furthermore, quick-xml also contains optional [Serde] support to directly
23//! serialize and deserialize from structs, without having to deal with the XML events.
24//! To get it enable the [`serialize`](#serialize) feature. Read more about mapping Rust types
25//! to XML in the documentation of [`de`] module. Also check [`serde_helpers`]
26//! module.
27//!
28//! # Examples
29//!
30//! - For a reading example see [`Reader`]
31//! - For a writing example see [`Writer`]
32//!
33//! # Features
34//!
35//! `quick-xml` supports the following features:
36//!
37//! [StAX]: https://en.wikipedia.org/wiki/StAX
38//! [tokio]: https://tokio.rs/
39//! [Serde]: https://serde.rs/
40//! [`de`]: ./de/index.html
41#![cfg_attr(
42 feature = "document-features",
43 cfg_attr(doc, doc = ::document_features::document_features!(
44 feature_label = "<a id=\"{feature}\" href=\"#{feature}\"><strong><code>{feature}</code></strong></a>"
45 ))
46)]
47#![forbid(unsafe_code)]
48#![deny(missing_docs)]
49#![recursion_limit = "1024"]
50// Enable feature requirements in the docs from 1.57
51// See https://stackoverflow.com/questions/61417452
52// docs.rs defines `docsrs` when building documentation
53// Since 1.92 `doc_auto_cfg` was merged into `doc_cfg`
54#![cfg_attr(docsrs, feature(doc_cfg))]
55#![warn(clippy::missing_const_for_fn)]
56
57#[cfg(feature = "serialize")]
58pub mod de;
59pub mod encoding;
60pub mod errors;
61pub mod escape;
62pub mod events;
63pub mod name;
64pub mod parser;
65pub mod reader;
66#[cfg(feature = "serialize")]
67pub mod se;
68#[cfg(feature = "serde-types")]
69pub mod serde_helpers;
70/// Not an official API, public for integration tests
71#[doc(hidden)]
72pub mod utils;
73pub mod writer;
74
75use std::borrow::Cow;
76
77// reexports
78pub use crate::encoding::Decoder;
79#[cfg(feature = "serialize")]
80pub use crate::errors::serialize::{DeError, SeError};
81pub use crate::errors::{Error, Result};
82pub use crate::reader::{NsReader, Reader};
83pub use crate::writer::{ElementWriter, Writer};
84
85/// Version of XML standard
86#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
87pub enum XmlVersion {
88 /// XML declaration was missed in the entity (root document or referenced
89 /// external DTD), so according to the specification, [version 1.0] is assumed.
90 /// Most documents in the world are still XML 1.0 documents.
91 ///
92 /// [version 1.0]: https://www.w3.org/TR/xml/
93 Implicit1_0,
94 /// XML version was specified as [`1.0`] in the entity (root document or referenced
95 /// external DTD).
96 ///
97 /// [`1.0`]: https://www.w3.org/TR/xml/
98 Explicit1_0,
99 /// XML version was specified as [`1.1`] in the entity (root document or referenced
100 /// external DTD).
101 ///
102 /// [`1.1`]: https://www.w3.org/TR/xml11/
103 Explicit1_1,
104}
105
106impl XmlVersion {
107 pub(crate) fn normalize_attribute_value<'input, 'entity, F>(
108 &self,
109 value: &'input str,
110 depth: usize,
111 resolve_entity: F,
112 ) -> std::result::Result<Cow<'input, str>, escape::EscapeError>
113 where
114 // the lifetime of the output comes from a capture or is `'static`
115 F: FnMut(&str) -> Option<&'entity str>,
116 {
117 match self {
118 Self::Explicit1_1 => {
119 escape::normalize_xml11_attribute_value(value, depth, resolve_entity)
120 }
121 _ => escape::normalize_xml10_attribute_value(value, depth, resolve_entity),
122 }
123 }
124}
125
126impl Default for XmlVersion {
127 #[inline]
128 fn default() -> Self {
129 Self::Implicit1_0
130 }
131}