Fetch only. This package fetches and parses the list. It does not screen names and it stores nothing. List data alone is not a clearance decision.

The UN Security Council Consolidated List (un): every individual and entity subject to Security Council sanctions, about 1,000 records.

Format used: the English XML file (https://scsanctions.un.org/resources/xml/en/consolidated.xml, about 2 MB; it redirects to a signed Azure Blob URL). It answers only GET, so there is no cheap version check: fetch downloads the file and compares the SHA-256 of the body with the version you pass, which saves the parse but not the download.

Example

out ::un::sanctions/fetch()
out.version
first(out.entries).name

Values

LIST_NAME

LIST_NAME: Str "UN Security Council Consolidated List"

MONTHS

MONTHS: Map {
  jan: "01",
  feb: "02",
  mar: "03",
  apr: "04",
  may: "05",
  jun: "06",
  jul: "07",
  aug: "08",
  sep: "09",
  oct: "10",
  nov: "11",
  dec: "12"
}

URL

URL: Str "https://scsanctions.un.org/resources/xml/en/consolidated.xml"

Functions

address-line

fn (node: Str): Str

blank-to-null

fn (v: Any): Str?

clean-list

fn (values: Vec): Vec<Str>

Trim strings, drop blanks and duplicates, keep the first-seen order.

dob-of

fn (node: Str): Str?

fetch

fn (): Map
fn (known-version: Str?): Map

Download and parse the UN list. Returns {version, entries, unchanged}, with Listing records in entries. version is the first 16 hex digits of the body's SHA-256. When it equals known-version, the file is not parsed, unchanged is true and entries is null. The server answers GET only, so the file is downloaded either way. A list that parses to no records is an Err.

Example

out ::un::sanctions/fetch()
again ::un::sanctions/fetch(out.version)
again.unchanged

iso-date

fn (raw: Str?): Str?

Normalize one published date of birth to ISO 8601, or null when it has no year. Accepts 1948-12-10, 10 Dec 1948, Dec 1948, 1948, circa 1948, 10/12/1948 and dd/mm/1948 (day first), and ranges such as 1959 to 1962 or 01 Jan 1960 to 31 Dec 1962 (1959/1962, 1960/1962).

Example

::un::sanctions/iso-date("10 Dec 1948")  // "1948-12-10"
::un::sanctions/iso-date("dd/mm/1963")   // "1963"
::un::sanctions/iso-date("1959 to 1962") // "1959/1962"

other-names

fn (aliases: Vec, name: Str): Vec<Str>

Cleaned aliases without the primary name, ignoring case.

pad2

fn (s: Str): Str

parse

fn (doc: Str): Vec<Listing>

Parse the whole UN consolidated XML into Listing records (pure).

parse-record

fn (record: Str, individual: Bool): Listing

Turn one <INDIVIDUAL> or <ENTITY> record string into a Listing; individual says which. Exposed for testing.

present

fn (v: Any): Bool

require-entries

fn (entries: Vec): Vec

The parsed records, or an Err when there are none: a changed file format can parse to nothing, and an empty list must not pass for a list with nobody on it.

Types

Listing

Listing type {
    id: Str,
    data-id: Str?,
    kind: ListingKind,
    name: Str,
    aliases: Vec<Str>,
    dobs: Vec<Str>,
    nationalities: Vec<Str>,
    list-types: Vec<Str>,
    addresses: Vec<Str>,
    comments: Str?,
    listed-on: Str?,
    url: Str
}

One <INDIVIDUAL> or <ENTITY>, as the consolidated XML publishes it.

Fields

  • id — the REFERENCE_NUMBER, e.g. "IQi.004"
  • data-id — the DATAID
  • kind — a ListingKind
  • name — FIRST_NAME to FOURTH_NAME, joined
  • aliases — every ALIAS_NAME, then NAME_ORIGINAL_SCRIPT
  • dobs — dates of birth as ISO 8601: YYYY-MM-DD, YYYY, or a range YYYY/YYYY
  • nationalities — as published
  • list-types — the UN_LIST_TYPE values
  • addresses — one line per address
  • comments — the COMMENTS1 text
  • listed-on — the LISTED_ON date, as published
  • url — the list file

ListingKind

ListingKind type "individual" | "entity"

What is listed: an <INDIVIDUAL> is "individual", an <ENTITY> is "entity".