|
5 | 5 | use crate::encoding::Decoder;
|
6 | 6 | use crate::errors::Result as XmlResult;
|
7 | 7 | use crate::escape::{escape, resolve_predefined_entity, unescape_with};
|
8 |
| -use crate::name::QName; |
| 8 | +use crate::name::{LocalName, Namespace, QName}; |
| 9 | +use crate::reader::NsReader; |
9 | 10 | use crate::utils::{is_whitespace, Bytes};
|
10 | 11 |
|
11 | 12 | use std::fmt::{self, Debug, Display, Formatter};
|
@@ -269,6 +270,81 @@ impl<'a> Attributes<'a> {
|
269 | 270 | self.state.check_duplicates = val;
|
270 | 271 | self
|
271 | 272 | }
|
| 273 | + |
| 274 | + /// Checks if the current tag has a [`xsi:nil`] attribute. This method ignores any errors in |
| 275 | + /// attributes. |
| 276 | + /// |
| 277 | + /// # Examples |
| 278 | + /// |
| 279 | + /// ``` |
| 280 | + /// # use pretty_assertions::assert_eq; |
| 281 | + /// use quick_xml::events::Event; |
| 282 | + /// use quick_xml::name::QName; |
| 283 | + /// use quick_xml::reader::NsReader; |
| 284 | + /// |
| 285 | + /// let mut reader = NsReader::from_str(" |
| 286 | + /// <root xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> |
| 287 | + /// <true xsi:nil='true'/> |
| 288 | + /// <false xsi:nil='false'/> |
| 289 | + /// <none/> |
| 290 | + /// <non-xsi xsi:nil='true' xmlns:xsi='namespace'/> |
| 291 | + /// <unbound-nil nil='true' xmlns='http://www.w3.org/2001/XMLSchema-instance'/> |
| 292 | + /// <another-xmlns f:nil='true' xmlns:f='http://www.w3.org/2001/XMLSchema-instance'/> |
| 293 | + /// </root> |
| 294 | + /// "); |
| 295 | + /// reader.config_mut().trim_text(true); |
| 296 | + /// |
| 297 | + /// macro_rules! check { |
| 298 | + /// ($reader:expr, $name:literal, $value:literal) => { |
| 299 | + /// let event = match $reader.read_event().unwrap() { |
| 300 | + /// Event::Empty(e) => e, |
| 301 | + /// e => panic!("Unexpected event {:?}", e), |
| 302 | + /// }; |
| 303 | + /// assert_eq!( |
| 304 | + /// (event.name(), event.attributes().has_nil(&$reader)), |
| 305 | + /// (QName($name.as_bytes()), $value), |
| 306 | + /// ); |
| 307 | + /// }; |
| 308 | + /// } |
| 309 | + /// |
| 310 | + /// let root = match reader.read_event().unwrap() { |
| 311 | + /// Event::Start(e) => e, |
| 312 | + /// e => panic!("Unexpected event {:?}", e), |
| 313 | + /// }; |
| 314 | + /// assert_eq!(root.attributes().has_nil(&reader), false); |
| 315 | + /// |
| 316 | + /// // definitely true |
| 317 | + /// check!(reader, "true", true); |
| 318 | + /// // definitely false |
| 319 | + /// check!(reader, "false", false); |
| 320 | + /// // absence of the attribute means that attribute is not set |
| 321 | + /// check!(reader, "none", false); |
| 322 | + /// // attribute not bound to the correct namespace |
| 323 | + /// check!(reader, "non-xsi", false); |
| 324 | + /// // attributes without prefix not bound to any namespace |
| 325 | + /// check!(reader, "unbound-nil", false); |
| 326 | + /// // prefix can be any while it is bound to the correct namespace |
| 327 | + /// check!(reader, "another-xmlns", true); |
| 328 | + /// ``` |
| 329 | + /// |
| 330 | + /// [`xsi:nil`]: https://www.w3.org/TR/xmlschema-1/#xsi_nil |
| 331 | + pub fn has_nil<R>(&mut self, reader: &NsReader<R>) -> bool { |
| 332 | + use crate::name::ResolveResult::*; |
| 333 | + |
| 334 | + self.any(|attr| { |
| 335 | + if let Ok(attr) = attr { |
| 336 | + match reader.resolve_attribute(attr.key) { |
| 337 | + ( |
| 338 | + Bound(Namespace(b"http://www.w3.org/2001/XMLSchema-instance")), |
| 339 | + LocalName(b"nil"), |
| 340 | + ) => attr.as_bool().unwrap_or_default(), |
| 341 | + _ => false, |
| 342 | + } |
| 343 | + } else { |
| 344 | + false |
| 345 | + } |
| 346 | + }) |
| 347 | + } |
272 | 348 | }
|
273 | 349 |
|
274 | 350 | impl<'a> Debug for Attributes<'a> {
|
|
0 commit comments