pub(crate) fn xml_enc_qattr(s: &str) -> String {
let mut out = String::with_capacity(s.len());
for c in s.chars() {
match c {
'<' => out.push_str("<"),
'>' => out.push_str(">"),
'&' => out.push_str("&"),
'"' => out.push_str("""),
_ => out.push(c),
}
}
out
}
pub(crate) fn xml_enc_nqg(s: &str) -> String {
let bytes: Vec<char> = s.chars().collect();
let mut out = String::with_capacity(s.len());
for (i, &c) in bytes.iter().enumerate() {
match c {
'<' => out.push_str("<"),
'&' => out.push_str("&"),
'>' if i >= 2 && bytes[i - 2] == ']' && bytes[i - 1] == ']' => out.push_str(">"),
_ => out.push(c),
}
}
out
}
pub(crate) fn is_xml_name_like(name: &str) -> bool {
if matches!(
name.chars().next(),
Some('/') | Some('@') | Some('*') | Some('[') | Some('.')
) {
return false;
}
let mut chars = name.chars();
match chars.next() {
Some(c) if c == '-' || c == '.' || c.is_ascii_digit() => return false,
Some(_) => {}
None => return false,
}
let mut colon = false;
for c in chars {
if c.is_alphanumeric() || c == '_' || c == '-' || c == '.' {
continue;
}
if c == ':' {
if colon {
return false; }
colon = true;
continue;
}
return false;
}
true
}