sup_xml_core/
ns_helpers.rs1use crate::error::{ErrorDomain, ErrorLevel, Result, XmlError};
10
11pub const XML_NS_URI: &str = "http://www.w3.org/XML/1998/namespace";
14pub const XMLNS_NS_URI: &str = "http://www.w3.org/2000/xmlns/";
15
16pub fn validate_qname(name: &str, context: &str) -> Result<()> {
21 if let Some(colon) = name.find(':') {
22 let prefix = &name[..colon];
23 let local = &name[colon + 1..];
24 if prefix.is_empty() {
25 return Err(ns_err(format!("empty prefix in {context} QName '{name}'")));
26 }
27 if local.is_empty() {
28 return Err(ns_err(format!("empty local part in {context} QName '{name}'")));
29 }
30 if local.contains(':') {
31 return Err(ns_err(format!("multiple ':' in {context} QName '{name}'")));
32 }
33 }
34 Ok(())
35}
36
37pub fn validate_xmlns_decl(local: &str, value: &str) -> Result<()> {
40 if local.is_empty() {
41 return Err(ns_err("empty local part in 'xmlns:' namespace declaration".into()));
42 }
43 if local == "xmlns" {
44 return Err(ns_err("prefix 'xmlns' must not be declared".into()));
45 }
46 if local == "xml" && value != XML_NS_URI {
47 return Err(ns_err(format!(
48 "prefix 'xml' must be bound to '{XML_NS_URI}', not '{value}'"
49 )));
50 }
51 if local != "xml" && value == XML_NS_URI {
52 return Err(ns_err(format!(
53 "prefix '{local}' cannot be bound to the XML namespace URI '{XML_NS_URI}'"
54 )));
55 }
56 if value == XMLNS_NS_URI {
57 return Err(ns_err(format!(
58 "prefix '{local}' cannot be bound to the xmlns namespace URI '{XMLNS_NS_URI}'"
59 )));
60 }
61 if value.is_empty() {
62 return Err(ns_err(format!(
63 "prefix '{local}' cannot be unbound (empty URI) in XML Namespaces 1.0"
64 )));
65 }
66 Ok(())
67}
68
69pub fn ns_err(msg: String) -> XmlError {
70 XmlError::new(ErrorDomain::Namespace, ErrorLevel::Fatal, msg)
71}