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}