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