spex/xml/xml_document.rs
1use crate::{xml::Element, xml::ProcessingInstruction};
2
3/**
4Represents the XML document, containing the root element and any processing instructions which
5appear outside of the root element.
6*/
7#[derive(Debug)]
8pub struct XmlDocument {
9 processing_instructions: Vec<ProcessingInstruction>,
10 root: Element,
11}
12
13impl XmlDocument {
14 pub(crate) fn new(
15 processing_instructions: Vec<ProcessingInstruction>,
16 root: Element,
17 ) -> XmlDocument {
18 XmlDocument {
19 processing_instructions,
20 root,
21 }
22 }
23
24 /**
25 Returns an iterator of references to all processing instructions contained within this
26 XML document **outside** of the root element.
27
28 # Examples
29
30 ```
31 # use std::fs::File;
32 # use spex::{parsing::XmlReader, xml::{XmlDocument, ProcessingInstruction,
33 # WhiteSpaceHandling}, common::XmlError};
34 # fn main() {
35 # let xml_doc = read_xml().unwrap();
36 # extract_xml(xml_doc).unwrap();
37 # }
38 #
39 # fn read_xml() -> Result<XmlDocument, std::io::Error> {
40 # let xml = "
41 <?document \n\t this processing instruction (PI) is not contained within the root element ?>
42 <root>
43 <?inside-root \n\t this PI is contained within the root element ?>
44 <?same-again also contained within root ?>
45 <child><?inner this PI is contained within the child element ?></child>
46 </root>
47 # ";
48 # let xml_doc = XmlReader::parse_auto(xml.as_bytes());
49 # xml_doc
50 # }
51 #
52
53 // The above XML is turned into an XmlDocument and passed to this method.
54 fn extract_xml(xml_doc: XmlDocument) -> Result<(), XmlError> {
55 let proc_ins: Vec<&ProcessingInstruction> = xml_doc.processing_instructions().collect();
56 # assert_eq!(proc_ins.len(), 1);
57 if let Some(first) = proc_ins.get(0) {
58 assert_eq!(first.target(), "document");
59 // Note that all whitespace between the PI target and the PI data is skipped, but
60 // any whitespace at the end of the data is returned.
61 assert_eq!(first.data(),
62 "this processing instruction (PI) is not contained within the root element ");
63 }
64 # else {panic!("Expected document processing instruction to exist!");}
65
66 Ok(())
67 }
68 ```
69 */
70 pub fn processing_instructions(&self) -> impl Iterator<Item = &ProcessingInstruction> {
71 self.processing_instructions.iter()
72 }
73
74 /**
75 Returns a reference to the root element of this XML document.
76
77 # Examples
78
79 ```
80 # use std::fs::File;
81 # use spex::{parsing::XmlReader, xml::{XmlDocument, ProcessingInstruction,
82 # WhiteSpaceHandling}, common::XmlError};
83 # fn main() {
84 # let xml_doc = read_xml().unwrap();
85 # extract_xml(xml_doc).unwrap();
86 # }
87 #
88 # fn read_xml() -> Result<XmlDocument, std::io::Error> {
89 # let xml = "
90 <PlayingNow>
91 <Track>
92 <Name>Lie</Name>
93 <Length>4m19s</Length>
94 <ByArtist>Black Light Burns</ByArtist>
95 <FromAlbum>Cruel Melody</FromAlbum>
96 </Track>
97 </PlayingNow>
98 # ";
99 # let xml_doc = XmlReader::parse_auto(xml.as_bytes());
100 # xml_doc
101 # }
102 #
103
104 // The above XML is turned into an XmlDocument and passed to this method.
105 fn extract_xml(xml_doc: XmlDocument) -> Result<(), XmlError> {
106 let root = xml_doc.root();
107 assert_eq!(root.name().local_part(), "PlayingNow");
108 Ok(())
109 }
110 ```
111 */
112 pub fn root(&self) -> &Element {
113 &self.root
114 }
115}