///|
const XLINK_URI : String = "http://www.w3.org/1999/xlink"
///|
fn namespaced_attribute(
element : XmlElementValue,
uri : String,
name : String,
) -> String? {
for attribute in element.attributes {
if attribute.namespace_uri == Some(uri) && attribute.name == name {
return Some(attribute.value)
}
}
None
}
///|
fn read_locator(element : XmlElementValue) -> Locator raise GraphError {
graphml_element(element, "locator")
require(
element_children(element).is_empty(),
"locator",
"locator must be empty",
)
let href = match namespaced_attribute(element, XLINK_URI, "href") {
Some(value) => value
None => raise InvalidGraph(path="locator", reason="missing xlink:href")
}
let link_type = namespaced_attribute(element, XLINK_URI, "type")
require(
link_type is None || link_type == Some("simple"),
"locator",
"xlink:type must be simple",
)
let extra = element.attributes.filter(fn(attribute) {
!(attribute.namespace_uri == Some(XLINK_URI) &&
(attribute.name == "href" || attribute.name == "type"))
})
{ href, link_type, extra, namespaces: element.namespaces, }
}
///|
fn find_locator(
children : Array[XmlElementValue],
owner : String,
) -> Locator? raise GraphError {
let mut locator : Locator? = None
for child in children {
if child.namespace_uri == Some(GRAPHML_URI) && child.name == "locator" {
require(locator is None, owner, "duplicate locator")
locator = Some(read_locator(child))
}
}
if locator is Some(_) {
require(
children.all(fn(child) { child.name == "desc" || child.name == "locator" }),
owner,
"locator cannot coexist with inline structure",
)
}
locator
}