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 namespace of this element, if it has one, else `None`.
195 pub fn ns(&self) -> Option<String> {
196 self.namespaces.get(&self.prefix)
197 }
198
199 /// Returns a reference to the value of the given attribute, if it exists, else `None`.
200 pub fn attr(&self, name: &str) -> Option<&str> {
201 if let Some(value) = self.attributes.get(name) {
202 return Some(value)
203 }
204 None
205 }
206
207 /// Returns an iterator over the attributes of this element.
208 ///
209 /// # Example
210 ///
211 /// ```rust
212 /// use minidom::Element;
213 ///
214 /// let elm: Element = "<elem a=\"b\" />".parse().unwrap();
215 ///
216 /// let mut iter = elm.attrs();
217 ///
218 /// assert_eq!(iter.next().unwrap(), ("a", "b"));
219 /// assert_eq!(iter.next(), None);
220 /// ```
221 pub fn attrs(&self) -> Attrs {
222 Attrs {
223 iter: self.attributes.iter(),
224 }
225 }
226
227 /// Returns an iterator over the attributes of this element, with the value being a mutable
228 /// reference.
229 pub fn attrs_mut(&mut self) -> AttrsMut {
230 AttrsMut {
231 iter: self.attributes.iter_mut(),
232 }
233 }
234
235 /// Modifies the value of an attribute.
236 pub fn set_attr<S: Into<String>, V: IntoAttributeValue>(&mut self, name: S, val: V) {
237 let name = name.into();
238 let val = val.into_attribute_value();
239
240 if let Some(value) = self.attributes.get_mut(&name) {
241 *value = val.expect("removing existing value via set_attr, this is not yet supported (TODO)"); // TODO
242 return;
243 }
244
245 if let Some(val) = val {
246 self.attributes.insert(name, val);
247 }
248 }
249
250 /// Returns whether the element has the given name and namespace.
251 ///
252 /// # Examples
253 ///
254 /// ```rust
255 /// use minidom::Element;
256 ///
257 /// let elem = Element::builder("name").ns("namespace").build();
258 ///
259 /// assert_eq!(elem.is("name", "namespace"), true);
260 /// assert_eq!(elem.is("name", "wrong"), false);
261 /// assert_eq!(elem.is("wrong", "namespace"), false);
262 /// assert_eq!(elem.is("wrong", "wrong"), false);
263 /// ```
264 pub fn is<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> bool {
265 self.name == name.as_ref() &&
266 self.has_ns(namespace)
267 }
268
269 /// Returns whether the element has the given namespace.
270 ///
271 /// # Examples
272 ///
273 /// ```rust
274 /// use minidom::Element;
275 ///
276 /// let elem = Element::builder("name").ns("namespace").build();
277 ///
278 /// assert_eq!(elem.has_ns("namespace"), true);
279 /// assert_eq!(elem.has_ns("wrong"), false);
280 /// ```
281 pub fn has_ns<NS: AsRef<str>>(&self, namespace: NS) -> bool {
282 self.namespaces.has(&self.prefix, namespace)
283 }
284
285 /// Parse a document from an `EventReader`.
286 pub fn from_reader<R: BufRead>(reader: &mut EventReader<R>) -> Result<Element> {
287 let mut buf = Vec::new();
288
289 let root: Element = loop {
290 let e = reader.read_event(&mut buf)?;
291 match e {
292 Event::Empty(ref e) | Event::Start(ref e) => {
293 break build_element(reader, e)?;
294 },
295 Event::Eof => {
296 bail!(ErrorKind::EndOfDocument);
297 },
298 Event::Text { .. } |
299 Event::End { .. } |
300 Event::Comment { .. } |
301 Event::CData { .. } |
302 Event::Decl { .. } |
303 Event::PI { .. } |
304 Event::DocType { .. } => (), // TODO: may need more errors
305 }
306 };
307
308 let mut stack = vec![root];
309
310 loop {
311 match reader.read_event(&mut buf)? {
312 Event::Empty(ref e) => {
313 let elem = build_element(reader, e)?;
314 // Since there is no Event::End after, directly append it to the current node
315 stack.last_mut().unwrap().append_child(elem);
316 },
317 Event::Start(ref e) => {
318 let elem = build_element(reader, e)?;
319 stack.push(elem);
320 },
321 Event::End(ref e) => {
322 if stack.len() <= 1 {
323 break;
324 }
325 let elem = stack.pop().unwrap();
326 if let Some(to) = stack.last_mut() {
327 if elem.name().as_bytes() != e.name() {
328 bail!(ErrorKind::InvalidElementClosed);
329 }
330 to.append_child(elem);
331 }
332 },
333 Event::Text(s) | Event::CData(s) => {
334 let text = s.unescape_and_decode(reader)?;
335 if text != "" {
336 let mut current_elem = stack.last_mut().unwrap();
337 current_elem.append_text_node(text);
338 }
339 },
340 Event::Eof => {
341 break;
342 },
343 Event::Comment { .. } |
344 Event::Decl { .. } |
345 Event::PI { .. } |
346 Event::DocType { .. } => (),
347 }
348 }
349 Ok(stack.pop().unwrap())
350 }
351
352 /// Output a document to a `Writer`.
353 pub fn write_to<W: Write>(&self, writer: &mut W) -> Result<()> {
354 write!(writer, "<?xml version=\"1.0\" encoding=\"utf-8\"?>")?;
355 self.write_to_inner(writer)
356 }
357
358 /// Like `write_to()` but without the `<?xml?>` prelude
359 pub fn write_to_inner<W: Write>(&self, writer: &mut W) -> Result<()> {
360 let name = match self.prefix {
361 None => Cow::Borrowed(&self.name),
362 Some(ref prefix) => Cow::Owned(format!("{}:{}", prefix, self.name)),
363 };
364 write!(writer, "<{}", name)?;
365
366 for (prefix, ns) in self.namespaces.declared_ns() {
367 match *prefix {
368 None => {
369 write!(writer, " xmlns=\"")?;
370 write_escaped(writer, ns)?;
371 write!(writer, "\"")?;
372 },
373 Some(ref prefix) => {
374 write!(writer, " xmlns:{}=\"", prefix)?;
375 write_escaped(writer, ns)?;
376 write!(writer, "\"")?;
377 },
378 }
379 }
380
381 for (key, value) in &self.attributes {
382 write!(writer, " {}=\"", key)?;
383 write_escaped(writer, value)?;
384 write!(writer, "\"")?;
385 }
386
387 if self.children.is_empty() {
388 write!(writer, " />")?;
389 return Ok(())
390 }
391
392 write!(writer, ">")?;
393
394 for child in &self.children {
395 child.write_to_inner(writer)?;
396 }
397
398 write!(writer, "</{}>", name)?;
399 Ok(())
400 }
401
402 /// Returns an iterator over references to every child node of this element.
403 ///
404 /// # Examples
405 ///
406 /// ```rust
407 /// use minidom::Element;
408 ///
409 /// let elem: Element = "<root>a<c1 />b<c2 />c</root>".parse().unwrap();
410 ///
411 /// let mut iter = elem.nodes();
412 ///
413 /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "a");
414 /// assert_eq!(iter.next().unwrap().as_element().unwrap().name(), "c1");
415 /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "b");
416 /// assert_eq!(iter.next().unwrap().as_element().unwrap().name(), "c2");
417 /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "c");
418 /// assert_eq!(iter.next(), None);
419 /// ```
420 #[inline] pub fn nodes(&self) -> Nodes {
421 self.children.iter()
422 }
423
424 /// Returns an iterator over mutable references to every child node of this element.
425 #[inline] pub fn nodes_mut(&mut self) -> NodesMut {
426 self.children.iter_mut()
427 }
428
429 /// Returns an iterator over references to every child element of this element.
430 ///
431 /// # Examples
432 ///
433 /// ```rust
434 /// use minidom::Element;
435 ///
436 /// let elem: Element = "<root>hello<child1 />this<child2 />is<child3 />ignored</root>".parse().unwrap();
437 ///
438 /// let mut iter = elem.children();
439 /// assert_eq!(iter.next().unwrap().name(), "child1");
440 /// assert_eq!(iter.next().unwrap().name(), "child2");
441 /// assert_eq!(iter.next().unwrap().name(), "child3");
442 /// assert_eq!(iter.next(), None);
443 /// ```
444 #[inline] pub fn children(&self) -> Children {
445 Children {
446 iter: self.children.iter(),
447 }
448 }
449
450 /// Returns an iterator over mutable references to every child element of this element.
451 #[inline] pub fn children_mut(&mut self) -> ChildrenMut {
452 ChildrenMut {
453 iter: self.children.iter_mut(),
454 }
455 }
456
457 /// Returns an iterator over references to every text node of this element.
458 ///
459 /// # Examples
460 ///
461 /// ```rust
462 /// use minidom::Element;
463 ///
464 /// let elem: Element = "<root>hello<c /> world!</root>".parse().unwrap();
465 ///
466 /// let mut iter = elem.texts();
467 /// assert_eq!(iter.next().unwrap(), "hello");
468 /// assert_eq!(iter.next().unwrap(), " world!");
469 /// assert_eq!(iter.next(), None);
470 /// ```
471 #[inline] pub fn texts(&self) -> Texts {
472 Texts {
473 iter: self.children.iter(),
474 }
475 }
476
477 /// Returns an iterator over mutable references to every text node of this element.
478 #[inline] pub fn texts_mut(&mut self) -> TextsMut {
479 TextsMut {
480 iter: self.children.iter_mut(),
481 }
482 }
483
484 /// Appends a child node to the `Element`, returning the appended node.
485 ///
486 /// # Examples
487 ///
488 /// ```rust
489 /// use minidom::Element;
490 ///
491 /// let mut elem = Element::bare("root");
492 ///
493 /// assert_eq!(elem.children().count(), 0);
494 ///
495 /// elem.append_child(Element::bare("child"));
496 ///
497 /// {
498 /// let mut iter = elem.children();
499 /// assert_eq!(iter.next().unwrap().name(), "child");
500 /// assert_eq!(iter.next(), None);
501 /// }
502 ///
503 /// let child = elem.append_child(Element::bare("new"));
504 ///
505 /// assert_eq!(child.name(), "new");
506 /// ```
507 pub fn append_child(&mut self, child: Element) -> &mut Element {
508 child.namespaces.set_parent(Rc::clone(&self.namespaces));
509
510 self.children.push(Node::Element(child));
511 if let Node::Element(ref mut cld) = *self.children.last_mut().unwrap() {
512 cld
513 } else {
514 unreachable!()
515 }
516 }
517
518 /// Appends a text node to an `Element`.
519 ///
520 /// # Examples
521 ///
522 /// ```rust
523 /// use minidom::Element;
524 ///
525 /// let mut elem = Element::bare("node");
526 ///
527 /// assert_eq!(elem.text(), "");
528 ///
529 /// elem.append_text_node("text");
530 ///
531 /// assert_eq!(elem.text(), "text");
532 /// ```
533 pub fn append_text_node<S: Into<String>>(&mut self, child: S) {
534 self.children.push(Node::Text(child.into()));
535 }
536
537 /// Appends a node to an `Element`.
538 ///
539 /// # Examples
540 ///
541 /// ```rust
542 /// use minidom::{Element, Node};
543 ///
544 /// let mut elem = Element::bare("node");
545 ///
546 /// elem.append_node(Node::Text("hello".to_owned()));
547 ///
548 /// assert_eq!(elem.text(), "hello");
549 /// ```
550 pub fn append_node(&mut self, node: Node) {
551 self.children.push(node);
552 }
553
554 /// Returns the concatenation of all text nodes in the `Element`.
555 ///
556 /// # Examples
557 ///
558 /// ```rust
559 /// use minidom::Element;
560 ///
561 /// let elem: Element = "<node>hello,<split /> world!</node>".parse().unwrap();
562 ///
563 /// assert_eq!(elem.text(), "hello, world!");
564 /// ```
565 pub fn text(&self) -> String {
566 self.texts().fold(String::new(), |ret, new| ret + new)
567 }
568
569 /// Returns a reference to the first child element with the specific name and namespace, if it
570 /// exists in the direct descendants of this `Element`, else returns `None`.
571 ///
572 /// # Examples
573 ///
574 /// ```rust
575 /// use minidom::Element;
576 ///
577 /// let elem: Element = r#"<node xmlns="ns"><a /><a xmlns="other_ns" /><b /></node>"#.parse().unwrap();
578 ///
579 /// assert!(elem.get_child("a", "ns").unwrap().is("a", "ns"));
580 /// assert!(elem.get_child("a", "other_ns").unwrap().is("a", "other_ns"));
581 /// assert!(elem.get_child("b", "ns").unwrap().is("b", "ns"));
582 /// assert_eq!(elem.get_child("c", "ns"), None);
583 /// assert_eq!(elem.get_child("b", "other_ns"), None);
584 /// assert_eq!(elem.get_child("a", "inexistent_ns"), None);
585 /// ```
586 pub fn get_child<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> Option<&Element> {
587 for fork in &self.children {
588 if let Node::Element(ref e) = *fork {
589 if e.is(name.as_ref(), namespace.as_ref()) {
590 return Some(e);
591 }
592 }
593 }
594 None
595 }
596
597 /// Returns a mutable reference to the first child element with the specific name and namespace,
598 /// if it exists in the direct descendants of this `Element`, else returns `None`.
599 pub fn get_child_mut<N: AsRef<str>, NS: AsRef<str>>(&mut self, name: N, namespace: NS) -> Option<&mut Element> {
600 for fork in &mut self.children {
601 if let Node::Element(ref mut e) = *fork {
602 if e.is(name.as_ref(), namespace.as_ref()) {
603 return Some(e);
604 }
605 }
606 }
607 None
608 }
609
610 /// Returns whether a specific child with this name and namespace exists in the direct
611 /// descendants of the `Element`.
612 ///
613 /// # Examples
614 ///
615 /// ```rust
616 /// use minidom::Element;
617 ///
618 /// let elem: Element = r#"<node xmlns="ns"><a /><a xmlns="other_ns" /><b /></node>"#.parse().unwrap();
619 ///
620 /// assert_eq!(elem.has_child("a", "other_ns"), true);
621 /// assert_eq!(elem.has_child("a", "ns"), true);
622 /// assert_eq!(elem.has_child("a", "inexistent_ns"), false);
623 /// assert_eq!(elem.has_child("b", "ns"), true);
624 /// assert_eq!(elem.has_child("b", "other_ns"), false);
625 /// assert_eq!(elem.has_child("b", "inexistent_ns"), false);
626 /// ```
627 pub fn has_child<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> bool {
628 self.get_child(name, namespace).is_some()
629 }
630}
631
632fn split_element_name<S: AsRef<str>>(s: S) -> Result<(Option<String>, String)> {
633 let name_parts = s.as_ref().split(':').collect::<Vec<&str>>();
634 match name_parts.len() {
635 2 => Ok((Some(name_parts[0].to_owned()), name_parts[1].to_owned())),
636 1 => Ok((None, name_parts[0].to_owned())),
637 _ => bail!(ErrorKind::InvalidElement),
638 }
639}
640
641fn build_element<R: BufRead>(reader: &EventReader<R>, event: &BytesStart) -> Result<Element> {
642 let mut namespaces = BTreeMap::new();
643 let attributes = event.attributes()
644 .map(|o| {
645 let o = o?;
646 let key = str::from_utf8(o.key)?.to_owned();
647 let value = o.unescape_and_decode_value(reader)?;
648 Ok((key, value))
649 })
650 .filter(|o| {
651 match *o {
652 Ok((ref key, ref value)) if key == "xmlns" => {
653 namespaces.insert(None, value.to_owned());
654 false
655 },
656 Ok((ref key, ref value)) if key.starts_with("xmlns:") => {
657 namespaces.insert(Some(key[6..].to_owned()), value.to_owned());
658 false
659 },
660 _ => true,
661 }
662 })
663 .collect::<Result<BTreeMap<String, String>>>()?;
664
665 let (prefix, name) = split_element_name(str::from_utf8(event.name())?)?;
666 let element = Element::new(name, prefix, namespaces, attributes, Vec::new());
667 Ok(element)
668}
669
670/// An iterator over references to child elements of an `Element`.
671pub struct Children<'a> {
672 iter: slice::Iter<'a, Node>,
673}
674
675impl<'a> Iterator for Children<'a> {
676 type Item = &'a Element;
677
678 fn next(&mut self) -> Option<&'a Element> {
679 for item in &mut self.iter {
680 if let Node::Element(ref child) = *item {
681 return Some(child);
682 }
683 }
684 None
685 }
686}
687
688/// An iterator over mutable references to child elements of an `Element`.
689pub struct ChildrenMut<'a> {
690 iter: slice::IterMut<'a, Node>,
691}
692
693impl<'a> Iterator for ChildrenMut<'a> {
694 type Item = &'a mut Element;
695
696 fn next(&mut self) -> Option<&'a mut Element> {
697 for item in &mut self.iter {
698 if let Node::Element(ref mut child) = *item {
699 return Some(child);
700 }
701 }
702 None
703 }
704}
705
706/// An iterator over references to child text nodes of an `Element`.
707pub struct Texts<'a> {
708 iter: slice::Iter<'a, Node>,
709}
710
711impl<'a> Iterator for Texts<'a> {
712 type Item = &'a str;
713
714 fn next(&mut self) -> Option<&'a str> {
715 for item in &mut self.iter {
716 if let Node::Text(ref child) = *item {
717 return Some(child);
718 }
719 }
720 None
721 }
722}
723
724/// An iterator over mutable references to child text nodes of an `Element`.
725pub struct TextsMut<'a> {
726 iter: slice::IterMut<'a, Node>,
727}
728
729impl<'a> Iterator for TextsMut<'a> {
730 type Item = &'a mut String;
731
732 fn next(&mut self) -> Option<&'a mut String> {
733 for item in &mut self.iter {
734 if let Node::Text(ref mut child) = *item {
735 return Some(child);
736 }
737 }
738 None
739 }
740}
741
742/// An iterator over references to all child nodes of an `Element`.
743pub type Nodes<'a> = slice::Iter<'a, Node>;
744
745/// An iterator over mutable references to all child nodes of an `Element`.
746pub type NodesMut<'a> = slice::IterMut<'a, Node>;
747
748/// An iterator over the attributes of an `Element`.
749pub struct Attrs<'a> {
750 iter: btree_map::Iter<'a, String, String>,
751}
752
753impl<'a> Iterator for Attrs<'a> {
754 type Item = (&'a str, &'a str);
755
756 fn next(&mut self) -> Option<Self::Item> {
757 self.iter.next().map(|(x, y)| (x.as_ref(), y.as_ref()))
758 }
759}
760
761/// An iterator over the attributes of an `Element`, with the values mutable.
762pub struct AttrsMut<'a> {
763 iter: btree_map::IterMut<'a, String, String>,
764}
765
766impl<'a> Iterator for AttrsMut<'a> {
767 type Item = (&'a str, &'a mut String);
768
769 fn next(&mut self) -> Option<Self::Item> {
770 self.iter.next().map(|(x, y)| (x.as_ref(), y))
771 }
772}
773
774/// A builder for `Element`s.
775pub struct ElementBuilder {
776 root: Element,
777 namespaces: BTreeMap<Option<String>, String>,
778}
779
780impl ElementBuilder {
781 /// Sets the namespace.
782 pub fn ns<S: Into<String>>(mut self, namespace: S) -> ElementBuilder {
783 self.namespaces
784 .insert(self.root.prefix.clone(), namespace.into());
785 self
786 }
787
788 /// Sets an attribute.
789 pub fn attr<S: Into<String>, V: IntoAttributeValue>(mut self, name: S, value: V) -> ElementBuilder {
790 self.root.set_attr(name, value);
791 self
792 }
793
794 /// Appends anything implementing `IntoElements` into the tree.
795 pub fn append<T: IntoElements>(mut self, into: T) -> ElementBuilder {
796 {
797 let mut emitter = ElementEmitter::new(&mut self.root);
798 into.into_elements(&mut emitter);
799 }
800 self
801 }
802
803 /// Builds the `Element`.
804 pub fn build(self) -> Element {
805 let mut element = self.root;
806 // Set namespaces
807 element.namespaces = Rc::new(NamespaceSet::from(self.namespaces));
808 // Propagate namespaces
809 for node in &element.children {
810 if let Node::Element(ref e) = *node {
811 e.namespaces.set_parent(Rc::clone(&element.namespaces));
812 }
813 }
814
815 element
816 }
817}
818
819#[cfg(test)]
820#[test]
821fn test_element_new() {
822 use std::iter::FromIterator;
823
824 let elem = Element::new( "name".to_owned()
825 , None
826 , Some("namespace".to_owned())
827 , BTreeMap::from_iter(vec![ ("name".to_string(), "value".to_string()) ].into_iter() )
828 , Vec::new() );
829
830 assert_eq!(elem.name(), "name");
831 assert_eq!(elem.ns(), Some("namespace".to_owned()));
832 assert_eq!(elem.attr("name"), Some("value"));
833 assert_eq!(elem.attr("inexistent"), None);
834}