1//! Provides an `Element` type, which represents DOM nodes, and a builder to create them with.
2
3use std::io:: Write;
4use std::collections::{btree_map, BTreeMap};
5
6use std::str;
7use std::cell::RefCell;
8use std::rc::Rc;
9
10use error::{Error, ErrorKind, Result};
11
12use quick_xml::reader::Reader as EventReader;
13use quick_xml::events::{Event, BytesStart};
14
15use std::io::BufRead;
16
17use std::str::FromStr;
18
19use std::slice;
20
21use convert::{IntoElements, IntoAttributeValue, ElementEmitter};
22
23/// Escape XML text
24pub fn write_escaped<W: Write>(writer: &mut W, input: &str) -> Result<()> {
25 for c in input.chars() {
26 match c {
27 '&' => write!(writer, "&")?,
28 '<' => write!(writer, "<")?,
29 '>' => write!(writer, ">")?,
30 '\'' => write!(writer, "'")?,
31 '"' => write!(writer, """)?,
32 _ => write!(writer, "{}", c)?,
33 }
34 }
35
36 Ok(())
37}
38
39/// A node in an element tree.
40#[derive(Clone, Debug, PartialEq, Eq)]
41pub enum Node {
42 /// An `Element`.
43 Element(Element),
44 /// A text node.
45 Text(String),
46}
47
48impl Node {
49 /// Turns this into an `Element` if possible, else returns None.
50 ///
51 /// # Examples
52 ///
53 /// ```rust
54 /// use minidom::Node;
55 ///
56 /// let elm = Node::Element("<meow />".parse().unwrap());
57 /// let txt = Node::Text("meow".to_owned());
58 ///
59 /// assert_eq!(elm.as_element().unwrap().name(), "meow");
60 /// assert_eq!(txt.as_element(), None);
61 /// ```
62 pub fn as_element(&self) -> Option<&Element> {
63 match *self {
64 Node::Element(ref e) => Some(e),
65 Node::Text(_) => None,
66 }
67 }
68
69 /// Turns this into a `String` if possible, else returns None.
70 ///
71 /// # Examples
72 ///
73 /// ```rust
74 /// use minidom::Node;
75 ///
76 /// let elm = Node::Element("<meow />".parse().unwrap());
77 /// let txt = Node::Text("meow".to_owned());
78 ///
79 /// assert_eq!(elm.as_text(), None);
80 /// assert_eq!(txt.as_text().unwrap(), "meow");
81 /// ```
82 pub fn as_text(&self) -> Option<&str> {
83 match *self {
84 Node::Element(_) => None,
85 Node::Text(ref s) => Some(s),
86 }
87 }
88
89 fn write_to_inner<W: Write>(&self, writer: &mut W) -> Result<()>{
90 match *self {
91 Node::Element(ref elmt) => elmt.write_to_inner(writer)?,
92 Node::Text(ref s) => write_escaped(writer, s)?,
93 }
94
95 Ok(())
96 }
97}
98
99#[derive(Clone, Debug, PartialEq, Eq)]
100struct NamespaceSet {
101 parent: RefCell<Option<Rc<NamespaceSet>>>,
102 namespaces: BTreeMap<Option<String>, String>,
103}
104
105impl Default for NamespaceSet {
106 fn default() -> Self {
107 NamespaceSet {
108 parent: RefCell::new(None),
109 namespaces: BTreeMap::new(),
110 }
111 }
112}
113
114impl NamespaceSet {
115 fn get(&self, prefix: &Option<String>) -> Option<String> {
116 match self.namespaces.get(prefix) {
117 Some(ns) => Some(ns.clone()),
118 None => match *self.parent.borrow() {
119 None => None,
120 Some(ref parent) => parent.get(prefix)
121 },
122 }
123 }
124
125 fn has<NS: AsRef<str>>(&self, prefix: &Option<String>, wanted_ns: NS) -> bool {
126 match self.namespaces.get(prefix) {
127 Some(ns) =>
128 ns == wanted_ns.as_ref(),
129 None => match *self.parent.borrow() {
130 None =>
131 false,
132 Some(ref parent) =>
133 parent.has(prefix, wanted_ns),
134 },
135 }
136 }
137
138 fn set_parent(&self, parent: &Element) {
139 let mut parent_ns = self.parent.borrow_mut();
140 let new_set = ((&parent.namespaces) as &Rc<NamespaceSet>).clone();
141 *parent_ns = Some(new_set);
142 }
143
144}
145
146impl From<BTreeMap<Option<String>, String>> for NamespaceSet {
147 fn from(namespaces: BTreeMap<Option<String>, String>) -> Self {
148 NamespaceSet {
149 parent: RefCell::new(None),
150 namespaces: namespaces,
151 }
152 }
153}
154
155impl From<Option<String>> for NamespaceSet {
156 fn from(namespace: Option<String>) -> Self {
157 match namespace {
158 None => Self::default(),
159 Some(namespace) => Self::from(namespace),
160 }
161 }
162}
163
164impl From<String> for NamespaceSet {
165 fn from(namespace: String) -> Self {
166 let mut namespaces = BTreeMap::new();
167 namespaces.insert(None, namespace);
168
169 NamespaceSet {
170 parent: RefCell::new(None),
171 namespaces: namespaces,
172 }
173 }
174}
175
176impl From<(Option<String>, String)> for NamespaceSet {
177 fn from(prefix_namespace: (Option<String>, String)) -> Self {
178 let (prefix, namespace) = prefix_namespace;
179 let mut namespaces = BTreeMap::new();
180 namespaces.insert(prefix, namespace);
181
182 NamespaceSet {
183 parent: RefCell::new(None),
184 namespaces: namespaces,
185 }
186 }
187}
188
189impl From<(String, String)> for NamespaceSet {
190 fn from(prefix_namespace: (String, String)) -> Self {
191 let (prefix, namespace) = prefix_namespace;
192 Self::from((Some(prefix), namespace))
193 }
194}
195
196#[derive(Clone, PartialEq, Eq, Debug)]
197/// A struct representing a DOM Element.
198pub struct Element {
199 prefix: Option<String>,
200 name: String,
201 namespaces: Rc<NamespaceSet>,
202 attributes: BTreeMap<String, String>,
203 children: Vec<Node>,
204}
205
206impl<'a> From<&'a Element> for String {
207 fn from(elem: &'a Element) -> String {
208 let mut writer = Vec::new();
209 elem.write_to(&mut writer).unwrap();
210 String::from_utf8(writer).unwrap()
211 }
212}
213
214
215impl FromStr for Element {
216 type Err = Error;
217
218 fn from_str(s: &str) -> Result<Element> {
219 let mut reader = EventReader::from_str(s);
220 Element::from_reader(&mut reader)
221 }
222}
223
224impl Element {
225 fn new<NS: Into<NamespaceSet>>(name: String, prefix: Option<String>, namespaces: NS, attributes: BTreeMap<String, String>, children: Vec<Node>) -> Element {
226 Element {
227 prefix, name,
228 namespaces: Rc::new(namespaces.into()),
229 attributes: attributes,
230 children: children,
231 }
232 }
233
234 /// Return a builder for an `Element` with the given `name`.
235 ///
236 /// # Examples
237 ///
238 /// ```rust
239 /// use minidom::Element;
240 ///
241 /// let elem = Element::builder("name")
242 /// .ns("namespace")
243 /// .attr("name", "value")
244 /// .append("inner")
245 /// .build();
246 ///
247 /// assert_eq!(elem.name(), "name");
248 /// assert_eq!(elem.ns(), Some("namespace".to_owned()));
249 /// assert_eq!(elem.attr("name"), Some("value"));
250 /// assert_eq!(elem.attr("inexistent"), None);
251 /// assert_eq!(elem.text(), "inner");
252 /// ```
253 pub fn builder<S: AsRef<str>>(name: S) -> ElementBuilder {
254 let (prefix, name) = split_element_name(name).unwrap();
255 ElementBuilder {
256 root: Element::new(name, prefix, None, BTreeMap::new(), Vec::new()),
257 namespaces: Default::default(),
258 }
259 }
260
261 /// Returns a bare minimum `Element` with this name.
262 ///
263 /// # Examples
264 ///
265 /// ```rust
266 /// use minidom::Element;
267 ///
268 /// let bare = Element::bare("name");
269 ///
270 /// assert_eq!(bare.name(), "name");
271 /// assert_eq!(bare.ns(), None);
272 /// assert_eq!(bare.attr("name"), None);
273 /// assert_eq!(bare.text(), "");
274 /// ```
275 pub fn bare<S: Into<String>>(name: S) -> Element {
276 Element {
277 prefix: None,
278 name: name.into(),
279 namespaces: Rc::new(NamespaceSet::default()),
280 attributes: BTreeMap::new(),
281 children: Vec::new(),
282 }
283 }
284
285 /// Returns a reference to the name of this element.
286 pub fn name(&self) -> &str {
287 &self.name
288 }
289
290 /// Returns a reference to the namespace of this element, if it has one, else `None`.
291 pub fn ns(&self) -> Option<String> {
292 self.namespaces.get(&self.prefix)
293 }
294
295 /// Returns a reference to the value of the given attribute, if it exists, else `None`.
296 pub fn attr(&self, name: &str) -> Option<&str> {
297 if let Some(value) = self.attributes.get(name) {
298 return Some(value)
299 }
300 None
301 }
302
303 /// Returns an iterator over the attributes of this element.
304 ///
305 /// # Example
306 ///
307 /// ```rust
308 /// use minidom::Element;
309 ///
310 /// let elm: Element = "<elem a=\"b\" />".parse().unwrap();
311 ///
312 /// let mut iter = elm.attrs();
313 ///
314 /// assert_eq!(iter.next().unwrap(), ("a", "b"));
315 /// assert_eq!(iter.next(), None);
316 /// ```
317 pub fn attrs(&self) -> Attrs {
318 Attrs {
319 iter: self.attributes.iter(),
320 }
321 }
322
323 /// Returns an iterator over the attributes of this element, with the value being a mutable
324 /// reference.
325 pub fn attrs_mut(&mut self) -> AttrsMut {
326 AttrsMut {
327 iter: self.attributes.iter_mut(),
328 }
329 }
330
331 /// Modifies the value of an attribute.
332 pub fn set_attr<S: Into<String>, V: IntoAttributeValue>(&mut self, name: S, val: V) {
333 let name = name.into();
334 let val = val.into_attribute_value();
335
336 if let Some(value) = self.attributes.get_mut(&name) {
337 *value = val.expect("removing existing value via set_attr, this is not yet supported (TODO)"); // TODO
338 return;
339 }
340
341 if let Some(val) = val {
342 self.attributes.insert(name, val);
343 }
344 }
345
346 /// Returns whether the element has the given name and namespace.
347 ///
348 /// # Examples
349 ///
350 /// ```rust
351 /// use minidom::Element;
352 ///
353 /// let elem = Element::builder("name").ns("namespace").build();
354 ///
355 /// assert_eq!(elem.is("name", "namespace"), true);
356 /// assert_eq!(elem.is("name", "wrong"), false);
357 /// assert_eq!(elem.is("wrong", "namespace"), false);
358 /// assert_eq!(elem.is("wrong", "wrong"), false);
359 /// ```
360 pub fn is<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> bool {
361 self.name == name.as_ref() &&
362 self.namespaces.has(&self.prefix, namespace)
363 }
364
365 /// Parse a document from an `EventReader`.
366 pub fn from_reader<R: BufRead>(reader: &mut EventReader<R>) -> Result<Element> {
367 let mut buf = Vec::new();
368 let root: Element;
369
370 loop {
371 let e = reader.read_event(&mut buf)?;
372 match e {
373 Event::Empty(ref e) | Event::Start(ref e) => {
374 root = build_element(e)?; // FIXME: could be break build_element(e)? when break value is stable
375 break;
376 },
377 Event::Eof => {
378 bail!(ErrorKind::EndOfDocument);
379 },
380 _ => () // TODO: may need more errors
381 }
382 };
383
384 let mut stack = vec![root];
385
386 loop {
387 match reader.read_event(&mut buf)? {
388 Event::Empty(ref e) => {
389 let elem = build_element(e)?;
390 // Since there is no Event::End after, directly append it to the current node
391 stack.last_mut().unwrap().append_child(elem);
392 },
393 Event::Start(ref e) => {
394 let elem = build_element(e)?;
395 stack.push(elem);
396 },
397 Event::End(ref e) => {
398 if stack.len() <= 1 {
399 break;
400 }
401 let elem = stack.pop().unwrap();
402 if let Some(to) = stack.last_mut() {
403 if elem.name().as_bytes() != e.name() {
404 bail!(ErrorKind::InvalidElementClosed);
405 }
406 to.append_child(elem);
407 }
408 },
409 Event::Text(s) | Event::CData(s) => {
410 let text = s.unescape_and_decode(reader)?;
411 if text != "" {
412 let mut current_elem = stack.last_mut().unwrap();
413 current_elem.append_text_node(text);
414 }
415 },
416 Event::Eof => {
417 break;
418 },
419 _ => (), // TODO: may need to implement more
420 }
421 }
422 Ok(stack.pop().unwrap())
423 }
424
425 /// Output a document to a `Writer`.
426 pub fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
427 write!(writer, "<?xml version=\"1.0\" encoding=\"utf-8\"?>")?;
428 self.write_to_inner(writer)
429 }
430
431 /// Like `write_to()` but without the `<?xml?>` prelude
432 pub fn write_to_inner<W: Write>(&self, writer: &mut W) -> Result<()> {
433 let name = match &self.prefix {
434 &None => self.name.to_owned(),
435 &Some(ref prefix) => format!("{}:{}", prefix, self.name),
436 };
437 write!(writer, "<{}", name)?;
438
439 for (prefix, ns) in &self.namespaces.namespaces {
440 match prefix {
441 &None => {
442 write!(writer, " xmlns=\"")?;
443 write_escaped(writer, ns)?;
444 write!(writer, "\"")?;
445 },
446 &Some(ref prefix) => {
447 write!(writer, " xmlns:{}=\"", prefix)?;
448 write_escaped(writer, ns)?;
449 write!(writer, "\"")?;
450 },
451 }
452 }
453
454 for (key, value) in &self.attributes {
455 write!(writer, " {}=\"", key)?;
456 write_escaped(writer, value)?;
457 write!(writer, "\"")?;
458 }
459
460 if self.children.is_empty() {
461 write!(writer, " />")?;
462 return Ok(())
463 }
464
465 write!(writer, ">")?;
466
467 for child in &self.children {
468 child.write_to_inner(writer)?;
469 }
470
471 write!(writer, "</{}>", name)?;
472 Ok(())
473 }
474
475 /// Returns an iterator over references to every child node of this element.
476 ///
477 /// # Examples
478 ///
479 /// ```rust
480 /// use minidom::Element;
481 ///
482 /// let elem: Element = "<root>a<c1 />b<c2 />c</root>".parse().unwrap();
483 ///
484 /// let mut iter = elem.nodes();
485 ///
486 /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "a");
487 /// assert_eq!(iter.next().unwrap().as_element().unwrap().name(), "c1");
488 /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "b");
489 /// assert_eq!(iter.next().unwrap().as_element().unwrap().name(), "c2");
490 /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "c");
491 /// assert_eq!(iter.next(), None);
492 /// ```
493 #[inline] pub fn nodes(&self) -> Nodes {
494 self.children.iter()
495 }
496
497 /// Returns an iterator over mutable references to every child node of this element.
498 #[inline] pub fn nodes_mut(&mut self) -> NodesMut {
499 self.children.iter_mut()
500 }
501
502 /// Returns an iterator over references to every child element of this element.
503 ///
504 /// # Examples
505 ///
506 /// ```rust
507 /// use minidom::Element;
508 ///
509 /// let elem: Element = "<root>hello<child1 />this<child2 />is<child3 />ignored</root>".parse().unwrap();
510 ///
511 /// let mut iter = elem.children();
512 /// assert_eq!(iter.next().unwrap().name(), "child1");
513 /// assert_eq!(iter.next().unwrap().name(), "child2");
514 /// assert_eq!(iter.next().unwrap().name(), "child3");
515 /// assert_eq!(iter.next(), None);
516 /// ```
517 #[inline] pub fn children(&self) -> Children {
518 Children {
519 iter: self.children.iter(),
520 }
521 }
522
523 /// Returns an iterator over mutable references to every child element of this element.
524 #[inline] pub fn children_mut(&mut self) -> ChildrenMut {
525 ChildrenMut {
526 iter: self.children.iter_mut(),
527 }
528 }
529
530 /// Returns an iterator over references to every text node of this element.
531 ///
532 /// # Examples
533 ///
534 /// ```rust
535 /// use minidom::Element;
536 ///
537 /// let elem: Element = "<root>hello<c /> world!</root>".parse().unwrap();
538 ///
539 /// let mut iter = elem.texts();
540 /// assert_eq!(iter.next().unwrap(), "hello");
541 /// assert_eq!(iter.next().unwrap(), " world!");
542 /// assert_eq!(iter.next(), None);
543 /// ```
544 #[inline] pub fn texts(&self) -> Texts {
545 Texts {
546 iter: self.children.iter(),
547 }
548 }
549
550 /// Returns an iterator over mutable references to every text node of this element.
551 #[inline] pub fn texts_mut(&mut self) -> TextsMut {
552 TextsMut {
553 iter: self.children.iter_mut(),
554 }
555 }
556
557 /// Appends a child node to the `Element`, returning the appended node.
558 ///
559 /// # Examples
560 ///
561 /// ```rust
562 /// use minidom::Element;
563 ///
564 /// let mut elem = Element::bare("root");
565 ///
566 /// assert_eq!(elem.children().count(), 0);
567 ///
568 /// elem.append_child(Element::bare("child"));
569 ///
570 /// {
571 /// let mut iter = elem.children();
572 /// assert_eq!(iter.next().unwrap().name(), "child");
573 /// assert_eq!(iter.next(), None);
574 /// }
575 ///
576 /// let child = elem.append_child(Element::bare("new"));
577 ///
578 /// assert_eq!(child.name(), "new");
579 /// ```
580 pub fn append_child(&mut self, child: Element) -> &mut Element {
581 child.namespaces.set_parent(&self);
582
583 self.children.push(Node::Element(child));
584 if let Node::Element(ref mut cld) = *self.children.last_mut().unwrap() {
585 cld
586 } else {
587 unreachable!()
588 }
589 }
590
591 /// Appends a text node to an `Element`.
592 ///
593 /// # Examples
594 ///
595 /// ```rust
596 /// use minidom::Element;
597 ///
598 /// let mut elem = Element::bare("node");
599 ///
600 /// assert_eq!(elem.text(), "");
601 ///
602 /// elem.append_text_node("text");
603 ///
604 /// assert_eq!(elem.text(), "text");
605 /// ```
606 pub fn append_text_node<S: Into<String>>(&mut self, child: S) {
607 self.children.push(Node::Text(child.into()));
608 }
609
610 /// Appends a node to an `Element`.
611 ///
612 /// # Examples
613 ///
614 /// ```rust
615 /// use minidom::{Element, Node};
616 ///
617 /// let mut elem = Element::bare("node");
618 ///
619 /// elem.append_node(Node::Text("hello".to_owned()));
620 ///
621 /// assert_eq!(elem.text(), "hello");
622 /// ```
623 pub fn append_node(&mut self, node: Node) {
624 self.children.push(node);
625 }
626
627 /// Returns the concatenation of all text nodes in the `Element`.
628 ///
629 /// # Examples
630 ///
631 /// ```rust
632 /// use minidom::Element;
633 ///
634 /// let elem: Element = "<node>hello,<split /> world!</node>".parse().unwrap();
635 ///
636 /// assert_eq!(elem.text(), "hello, world!");
637 /// ```
638 pub fn text(&self) -> String {
639 self.texts().fold(String::new(), |ret, new| ret + new)
640 }
641
642 /// Returns a reference to the first child element with the specific name and namespace, if it
643 /// exists in the direct descendants of this `Element`, else returns `None`.
644 ///
645 /// # Examples
646 ///
647 /// ```rust
648 /// use minidom::Element;
649 ///
650 /// let elem: Element = r#"<node xmlns="ns"><a /><a xmlns="other_ns" /><b /></node>"#.parse().unwrap();
651 ///
652 /// assert!(elem.get_child("a", "ns").unwrap().is("a", "ns"));
653 /// assert!(elem.get_child("a", "other_ns").unwrap().is("a", "other_ns"));
654 /// assert!(elem.get_child("b", "ns").unwrap().is("b", "ns"));
655 /// assert_eq!(elem.get_child("c", "ns"), None);
656 /// assert_eq!(elem.get_child("b", "other_ns"), None);
657 /// assert_eq!(elem.get_child("a", "inexistent_ns"), None);
658 /// ```
659 pub fn get_child<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> Option<&Element> {
660 for fork in &self.children {
661 if let Node::Element(ref e) = *fork {
662 if e.is(name.as_ref(), namespace.as_ref()) {
663 return Some(e);
664 }
665 }
666 }
667 None
668 }
669
670 /// Returns a mutable reference to the first child element with the specific name and namespace,
671 /// if it exists in the direct descendants of this `Element`, else returns `None`.
672 pub fn get_child_mut<N: AsRef<str>, NS: AsRef<str>>(&mut self, name: N, namespace: NS) -> Option<&mut Element> {
673 for fork in &mut self.children {
674 if let Node::Element(ref mut e) = *fork {
675 if e.is(name.as_ref(), namespace.as_ref()) {
676 return Some(e);
677 }
678 }
679 }
680 None
681 }
682
683 /// Returns whether a specific child with this name and namespace exists in the direct
684 /// descendants of the `Element`.
685 ///
686 /// # Examples
687 ///
688 /// ```rust
689 /// use minidom::Element;
690 ///
691 /// let elem: Element = r#"<node xmlns="ns"><a /><a xmlns="other_ns" /><b /></node>"#.parse().unwrap();
692 ///
693 /// assert_eq!(elem.has_child("a", "other_ns"), true);
694 /// assert_eq!(elem.has_child("a", "ns"), true);
695 /// assert_eq!(elem.has_child("a", "inexistent_ns"), false);
696 /// assert_eq!(elem.has_child("b", "ns"), true);
697 /// assert_eq!(elem.has_child("b", "other_ns"), false);
698 /// assert_eq!(elem.has_child("b", "inexistent_ns"), false);
699 /// ```
700 pub fn has_child<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> bool {
701 self.get_child(name, namespace).is_some()
702 }
703}
704
705fn split_element_name<S: AsRef<str>>(s: S) -> Result<(Option<String>, String)> {
706 let name_parts = s.as_ref().split(':').collect::<Vec<&str>>();
707 match name_parts.len() {
708 2 => Ok((Some(name_parts[0].to_owned()), name_parts[1].to_owned())),
709 1 => Ok((None, name_parts[0].to_owned())),
710 _ => bail!(ErrorKind::InvalidElement),
711 }
712}
713
714fn build_element(event: &BytesStart) -> Result<Element> {
715 let mut namespaces = BTreeMap::new();
716 let attributes = event.attributes()
717 .map(|o| {
718 let o = o?;
719 let key = str::from_utf8(o.key)?.to_owned();
720 let value = str::from_utf8(o.value)?.to_owned();
721 Ok((key, value))
722 })
723 .filter(|o| {
724 match o {
725 &Ok((ref key, ref value)) if key == "xmlns" => {
726 namespaces.insert(None, value.to_owned());
727 false
728 },
729 &Ok((ref key, ref value)) if key.starts_with("xmlns:") => {
730 namespaces.insert(Some(key[6..].to_owned()), value.to_owned());
731 false
732 },
733 _ => true,
734 }
735 })
736 .collect::<Result<BTreeMap<String, String>>>()?;
737
738 let (prefix, name) = split_element_name(str::from_utf8(event.name())?)?;
739 let element = Element::new(name, prefix, namespaces, attributes, Vec::new());
740 Ok(element)
741}
742
743/// An iterator over references to child elements of an `Element`.
744pub struct Children<'a> {
745 iter: slice::Iter<'a, Node>,
746}
747
748impl<'a> Iterator for Children<'a> {
749 type Item = &'a Element;
750
751 fn next(&mut self) -> Option<&'a Element> {
752 for item in &mut self.iter {
753 if let Node::Element(ref child) = *item {
754 return Some(child);
755 }
756 }
757 None
758 }
759}
760
761/// An iterator over mutable references to child elements of an `Element`.
762pub struct ChildrenMut<'a> {
763 iter: slice::IterMut<'a, Node>,
764}
765
766impl<'a> Iterator for ChildrenMut<'a> {
767 type Item = &'a mut Element;
768
769 fn next(&mut self) -> Option<&'a mut Element> {
770 for item in &mut self.iter {
771 if let Node::Element(ref mut child) = *item {
772 return Some(child);
773 }
774 }
775 None
776 }
777}
778
779/// An iterator over references to child text nodes of an `Element`.
780pub struct Texts<'a> {
781 iter: slice::Iter<'a, Node>,
782}
783
784impl<'a> Iterator for Texts<'a> {
785 type Item = &'a str;
786
787 fn next(&mut self) -> Option<&'a str> {
788 for item in &mut self.iter {
789 if let Node::Text(ref child) = *item {
790 return Some(child);
791 }
792 }
793 None
794 }
795}
796
797/// An iterator over mutable references to child text nodes of an `Element`.
798pub struct TextsMut<'a> {
799 iter: slice::IterMut<'a, Node>,
800}
801
802impl<'a> Iterator for TextsMut<'a> {
803 type Item = &'a mut String;
804
805 fn next(&mut self) -> Option<&'a mut String> {
806 for item in &mut self.iter {
807 if let Node::Text(ref mut child) = *item {
808 return Some(child);
809 }
810 }
811 None
812 }
813}
814
815/// An iterator over references to all child nodes of an `Element`.
816pub type Nodes<'a> = slice::Iter<'a, Node>;
817
818/// An iterator over mutable references to all child nodes of an `Element`.
819pub type NodesMut<'a> = slice::IterMut<'a, Node>;
820
821/// An iterator over the attributes of an `Element`.
822pub struct Attrs<'a> {
823 iter: btree_map::Iter<'a, String, String>,
824}
825
826impl<'a> Iterator for Attrs<'a> {
827 type Item = (&'a str, &'a str);
828
829 fn next(&mut self) -> Option<Self::Item> {
830 self.iter.next().map(|(x, y)| (x.as_ref(), y.as_ref()))
831 }
832}
833
834/// An iterator over the attributes of an `Element`, with the values mutable.
835pub struct AttrsMut<'a> {
836 iter: btree_map::IterMut<'a, String, String>,
837}
838
839impl<'a> Iterator for AttrsMut<'a> {
840 type Item = (&'a str, &'a mut String);
841
842 fn next(&mut self) -> Option<Self::Item> {
843 self.iter.next().map(|(x, y)| (x.as_ref(), y))
844 }
845}
846
847/// A builder for `Element`s.
848pub struct ElementBuilder {
849 root: Element,
850 namespaces: BTreeMap<Option<String>, String>,
851}
852
853impl ElementBuilder {
854 /// Sets the namespace.
855 pub fn ns<S: Into<String>>(mut self, namespace: S) -> ElementBuilder {
856 self.namespaces
857 .insert(self.root.prefix.clone(), namespace.into());
858 self
859 }
860
861 /// Sets an attribute.
862 pub fn attr<S: Into<String>, V: IntoAttributeValue>(mut self, name: S, value: V) -> ElementBuilder {
863 self.root.set_attr(name, value);
864 self
865 }
866
867 /// Appends anything implementing `IntoElements` into the tree.
868 pub fn append<T: IntoElements>(mut self, into: T) -> ElementBuilder {
869 {
870 let mut emitter = ElementEmitter::new(&mut self.root);
871 into.into_elements(&mut emitter);
872 }
873 self
874 }
875
876 /// Builds the `Element`.
877 pub fn build(self) -> Element {
878 let mut element = self.root;
879 // Set namespaces
880 element.namespaces = Rc::new(NamespaceSet::from(self.namespaces));
881 // Propagate namespaces
882 for node in &element.children {
883 if let Node::Element(ref e) = *node {
884 e.namespaces.set_parent(&element);
885 }
886 }
887
888 element
889 }
890}
891
892#[cfg(test)]
893#[test]
894fn test_element_new() {
895 use std::iter::FromIterator;
896
897 let elem = Element::new( "name".to_owned()
898 , None
899 , Some("namespace".to_owned())
900 , BTreeMap::from_iter(vec![ ("name".to_string(), "value".to_string()) ].into_iter() )
901 , Vec::new() );
902
903 assert_eq!(elem.name(), "name");
904 assert_eq!(elem.ns(), Some("namespace".to_owned()));
905 assert_eq!(elem.attr("name"), Some("value"));
906 assert_eq!(elem.attr("inexistent"), None);
907}