///|
/// Serialize the document with an XML declaration.
pub fn Document::to_xml(self : Document) -> String {
  let w = Writer::new()
  w.write_decl()
  self.root.write_to(w)
  w.to_string()
}

///|
/// Serialize just this element (no XML declaration).
pub fn Element::to_xml(self : Element) -> String {
  let w = Writer::new()
  self.write_to(w)
  w.to_string()
}

///|
fn Element::write_to(self : Element, w : Writer) -> Unit {
  if self.children is [] {
    w.empty(self.name, attrs=self.attr_pairs())
  } else {
    w.open_with(self.name, attrs=self.attr_pairs())
    for child in self.children {
      child.write_to(w)
    }
    w.close(self.name)
  }
}

///|
fn Node::write_to(self : Node, w : Writer) -> Unit {
  match self {
    Text(s) => w.text(s)
    CData(s) => w.cdata(s)
    Element(el) => el.write_to(w)
  }
}

///|
fn Element::attr_pairs(self : Element) -> Array[(String, String)] {
  [
    for a in self.attrs => (a.key, a.value)
  ]
}