case-order=upper-first/lower-first makes the string comparison case-insensitive, with case used only to break ties among otherwise-equal strings; without it the default codepoint order is unchanged. Part of #82.
38 lines
1.9 KiB
Swift
38 lines
1.9 KiB
Swift
extension PureXML.XSLT.Transformer {
|
|
/// Compares strings case-insensitively, with `caseOrder` breaking ties among
|
|
/// strings that differ only in case (the XSLT `case-order` semantics).
|
|
static func caseInsensitiveCompare(_ left: String, _ right: String, _ caseOrder: PureXML.XSLT.CaseOrder) -> Int {
|
|
let leftLower = left.lowercased()
|
|
let rightLower = right.lowercased()
|
|
if leftLower != rightLower { return leftLower < rightLower ? -1 : 1 }
|
|
if left == right { return 0 }
|
|
// Equal apart from case: codepoint order puts uppercase first.
|
|
let upperFirst = left < right
|
|
let leftFirst = caseOrder == .upperFirst ? upperFirst : !upperFirst
|
|
return leftFirst ? -1 : 1
|
|
}
|
|
|
|
/// Rewrites a literal name in an `xsl:namespace-alias`ed stylesheet namespace
|
|
/// to its result namespace and prefix; other names pass through unchanged.
|
|
func aliased(_ name: PureXML.Model.QualifiedName) -> PureXML.Model.QualifiedName {
|
|
guard let alias = stylesheet.namespaceAliases[name.namespaceURI ?? ""] else { return name }
|
|
return PureXML.Model.QualifiedName(prefix: alias.prefix, localName: name.localName, namespaceURI: alias.uri)
|
|
}
|
|
|
|
/// The attributes with duplicates by name removed, keeping the last (so a
|
|
/// later attribute overrides one from an attribute set or an earlier source).
|
|
static func deduplicated(_ attributes: [PureXML.Model.Attribute]) -> [PureXML.Model.Attribute] {
|
|
var indexByName: [String: Int] = [:]
|
|
var result: [PureXML.Model.Attribute] = []
|
|
for attribute in attributes {
|
|
if let index = indexByName[attribute.name.description] {
|
|
result[index] = attribute
|
|
} else {
|
|
indexByName[attribute.name.description] = result.count
|
|
result.append(attribute)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
}
|