///|
/// Reference tools emit some non-XSD scalar spellings; tolerance must be explicitly requested.
pub(all) enum ReadProfile {
Strict
ReferenceLibraries
} derive(Eq, @debug.Debug)
///|
pub extend ReadProfile with Eq::{equal, not_equal}
///|
pub extend ReadProfile with @debug.Debug::{to_repr}
///|
fn reference_lexical(kind : String?, input : String) -> String {
let token = input.trim(chars=" \t\r\n").to_owned()
match (kind, token) {
(Some("boolean"), "True") => "true"
(Some("boolean"), "False") => "false"
(Some("float" | "double"), "inf") => "INF"
(Some("float" | "double"), "-inf") => "-INF"
(Some("float" | "double"), "nan") => "NaN"
_ => input
}
}
///|
fn normalize_reference_element(
element : XmlElementValue,
kinds : Map[String, String],
default_kind : String?,
) -> Unit raise GraphError {
if element.namespace_uri != Some(GRAPHML_URI) {
return
}
let kind = match element.name {
"data" =>
match attribute_value(element, "key") {
Some(id) => kinds.get(id)
None => None
}
"default" => default_kind
_ => None
}
if kind is Some(_) && element.content.all(fn(value) { value is Text(_) }) {
let original = element_text(element)
let normalized = reference_lexical(kind, original)
if normalized != original {
element.content.clear()
element.content.push(Text(normalized))
}
}
// XML extension payloads and string values are opaque, even if they use GraphML names.
if element.name == "data" || element.name == "default" {
return
}
let next_default = if element.name == "key" {
attribute_value(element, "attr.type")
} else {
None
}
for value in element.content {
if value is Element(child) {
normalize_reference_element(child, kinds, next_default)
}
}
}
///|
fn normalize_reference_tree(root : XmlElementValue) -> Unit raise GraphError {
let kinds : Map[String, String] = Map([])
for child in element_children(root) {
if child.namespace_uri == Some(GRAPHML_URI) && child.name == "key" {
if attribute_value(child, "id") is Some(id) &&
attribute_value(child, "attr.type") is Some(kind) {
kinds[id] = kind
}
}
}
normalize_reference_element(root, kinds, None)
}