Skip to content

namespaces

xsdata.utils.namespaces

load_prefix(uri, ns_map)

Get or create a prefix for the uri in the prefix-URI map.

Source code in xsdata/utils/namespaces.py
17
18
19
20
21
22
23
def load_prefix(uri: str, ns_map: Dict) -> Optional[str]:
    """Get or create a prefix for the uri in the prefix-URI map."""
    for prefix, ns in ns_map.items():
        if ns == uri:
            return prefix

    return generate_prefix(uri, ns_map)

generate_prefix(uri, ns_map)

Generate a prefix for the given uri and append it in the prefix-URI map.

Source code in xsdata/utils/namespaces.py
26
27
28
29
30
31
32
33
34
35
36
37
def generate_prefix(uri: str, ns_map: Dict) -> str:
    """Generate a prefix for the given uri and append it in the prefix-URI map."""
    namespace = Namespace.get_enum(uri)
    if namespace:
        prefix = namespace.prefix
    else:
        number = len(ns_map)
        prefix = f"ns{number}"

    ns_map[prefix] = uri

    return prefix

prefix_exists(uri, ns_map)

Check if the uri exists in the prefix-URI namespace mapping.

Source code in xsdata/utils/namespaces.py
40
41
42
def prefix_exists(uri: str, ns_map: Dict) -> bool:
    """Check if the uri exists in the prefix-URI namespace mapping."""
    return uri in ns_map.values()

is_default(uri, ns_map)

Check if the uri exists and it has no prefix.

Source code in xsdata/utils/namespaces.py
45
46
47
def is_default(uri: str, ns_map: Dict) -> bool:
    """Check if the uri exists and it has no prefix."""
    return any(uri == ns and not prefix for prefix, ns in ns_map.items())

clean_prefixes(ns_map)

Remove default namespace if it's also assigned to a prefix.

Source code in xsdata/utils/namespaces.py
50
51
52
53
54
55
56
57
58
59
60
61
62
63
def clean_prefixes(ns_map: Dict) -> Dict:
    """Remove default namespace if it's also assigned to a prefix."""
    result = {}
    for prefix, ns in ns_map.items():
        if ns:
            prefix = prefix or None
            if prefix not in result:
                result[prefix] = ns

    default_ns = result.get(None)
    if default_ns and any(prefix and ns == default_ns for prefix, ns in result.items()):
        result.pop(None)

    return result

clean_uri(namespace)

Remove common prefixes and suffixes from an URI string.

Source code in xsdata/utils/namespaces.py
66
67
68
69
70
71
72
73
74
75
76
77
78
def clean_uri(namespace: str) -> str:
    """Remove common prefixes and suffixes from an URI string."""
    if namespace[:2] == "##":
        namespace = namespace[2:]

    left, right = text.split(namespace)

    if left == "urn":
        namespace = right
    elif left in ("http", "https"):
        namespace = right[2:]

    return "_".join(x for x in namespace.split(".") if x not in __uri_ignore__)

build_qname(tag_or_uri, tag=None) cached

Create namespace qualified strings.

Source code in xsdata/utils/namespaces.py
81
82
83
84
85
86
87
88
89
90
@functools.lru_cache(maxsize=50)
def build_qname(tag_or_uri: Optional[str], tag: Optional[str] = None) -> str:
    """Create namespace qualified strings."""
    if not tag_or_uri:
        if not tag:
            raise ValueError("Invalid input both uri and tag are empty.")

        return tag

    return f"{{{tag_or_uri}}}{tag}" if tag else tag_or_uri

split_qname(qname) cached

Split namespace qualified strings.

Source code in xsdata/utils/namespaces.py
 93
 94
 95
 96
 97
 98
 99
100
101
@functools.lru_cache(maxsize=50)
def split_qname(qname: str) -> Tuple:
    """Split namespace qualified strings."""
    if qname[0] == "{":
        left, right = text.split(qname[1:], "}")
        if left:
            return left, right

    return None, qname

target_uri(qname)

Return the URI namespace of the qname.

Source code in xsdata/utils/namespaces.py
104
105
106
def target_uri(qname: str) -> Optional[str]:
    """Return the URI namespace of the qname."""
    return split_qname(qname)[0]

local_name(qname)

Return the local name of the qname.

Source code in xsdata/utils/namespaces.py
109
110
111
def local_name(qname: str) -> str:
    """Return the local name of the qname."""
    return split_qname(qname)[1]

is_ncname(name)

Verify given string is a valid ncname.

Source code in xsdata/utils/namespaces.py
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
def is_ncname(name: Optional[str]) -> bool:
    """Verify given string is a valid ncname."""
    if not name:
        return False

    char = name[0]
    if not char.isalpha() and char != "_":
        return False

    for char in name[1:]:
        if char.isalpha() or char.isdigit() or char in NCNAME_PUNCTUATION:
            continue

        return False

    return True

is_uri(uri)

Verify given string is a valid uri.

Source code in xsdata/utils/namespaces.py
135
136
137
def is_uri(uri: Optional[str]) -> bool:
    """Verify given string is a valid uri."""
    return bool(URI_REGEX.search(uri)) if uri else False

to_package_name(uri) cached

Util method to convert a namespace to a dot style package name.

Source code in xsdata/utils/namespaces.py
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
@functools.lru_cache(maxsize=50)
def to_package_name(uri: Optional[str]) -> str:
    """Util method to convert a namespace to a dot style package name."""
    if not uri:
        return ""

    # Remove scheme
    domain_sep = "."
    if uri.startswith("http://"):
        uri = uri[7:]
    elif uri.startswith("urn:"):
        uri = uri[4:]
        domain_sep = "-"

        if uri.startswith("xmlns:"):
            uri = uri[6:]

        uri = uri.replace(":", "/")

    # Remote target
    pos = uri.find("#")
    if pos > 0:
        uri = uri[:pos]

    tokens = [token for token in uri.split("/") if token.strip()]

    if not tokens:
        return ""

    # Remove extension
    if len(tokens) > 1:
        last = tokens[-1]
        pos = tokens[-1].rfind(".")
        if pos > 0:
            tokens[-1] = last[:pos]

    # Remove port from domain
    domain = tokens.pop(0)
    pos = domain.find(":")
    if pos > 0:
        domain = domain[:pos]

    # Remove www from domain
    if domain.startswith("www"):
        domain = domain[3:]

    for part in domain.split(domain_sep):
        tokens.insert(0, part)

    return ".".join(token for token in tokens if token)