CDA and clinical XML guide

CDA XML Namespaces Explained: Default Namespaces, Prefixes and XPath Failures

A CDA document can be well-formed and visibly contain a ClinicalDocument, section or observation element while an XPath query returns no results. The usual cause is a namespace mismatch: CDA elements belong to urn:hl7-org:v3, but the query is looking for elements with the same local names in no namespace. This guide explains the default CDA namespace, prefix mappings and a repeatable way to diagnose empty XPath results.

By Health Data ToolsPublished 30 July 2026Technically reviewed 30 July 2026Approx. 10-minute read
Compare namespace URIs, not visible prefixes. The prefix cda is only a local label. An unprefixed CDA element and a cda:-prefixed element represent the same expanded name when both resolve to urn:hl7-org:v3.

Overview

Why a valid-looking CDA returns zero XPath nodes

The published CDA core model identifies the XML namespace for ClinicalDocument as urn:hl7-org:v3.[1] A typical document makes that namespace the default:

<ClinicalDocument xmlns="urn:hl7-org:v3">
  <id root="2.16.840.1.113883.999.1" extension="DOC-001"/>
  <component>
    <structuredBody>
      <component>
        <section>
          <title>Synthetic Summary</title>
        </section>
      </component>
    </structuredBody>
  </component>
</ClinicalDocument>

The element is written as ClinicalDocument, but its expanded name is the pair {urn:hl7-org:v3}ClinicalDocument. The same applies to its unprefixed descendant elements while the default namespace remains in scope.

An XPath such as //ClinicalDocument/component/structuredBody commonly returns an empty result in XPath 1.0 because each unprefixed name test means “this local name in no namespace”. The query does not inherit the default namespace declared by the XML document.[3]

XML identity

An element name contains a namespace URI and a local name

Namespaces in XML defines an expanded name as a namespace name combined with a local name.[2] Prefixes are a compact way to bind those names in a document; the prefix text is not the namespace identity.

XML formNamespace URILocal nameSame expanded name?
<ClinicalDocument xmlns="urn:hl7-org:v3">urn:hl7-org:v3ClinicalDocumentYes
<cda:ClinicalDocument xmlns:cda="urn:hl7-org:v3">urn:hl7-org:v3ClinicalDocumentYes
<ClinicalDocument>NoneClinicalDocumentNo
<x:ClinicalDocument xmlns:x="urn:example:extension">urn:example:extensionClinicalDocumentNo

This is why changing cda: to another prefix does not change the element's namespace-aware identity when the new prefix is bound to the same URI. Removing the namespace declaration or binding the prefix to a different URI does change that identity.

Default namespace

The default applies to elements, not ordinary attributes

A default namespace declaration applies to unprefixed element names within its scope. It does not apply directly to unprefixed attribute names.[2] In the following CDA fragment, id is in the CDA namespace, while root and extension are in no namespace:

<id root="2.16.840.1.113883.999.1" extension="DOC-001"/>

A namespace-aware XPath therefore uses a prefix for the element but not for those attributes:

//cda:id/@root
//cda:id/@extension

Do not automatically prefix every attribute. //cda:id/@cda:root looks for an attribute named root in the CDA namespace, which is not the same as the ordinary unprefixed root attribute.

Namespace declarations are scoped. A descendant can bind a new default namespace, change an existing prefix or clear the default namespace with xmlns="". Inspect the declarations in scope at the failing node rather than assuming that the root declaration applies unchanged to the whole document.

XPath 1.0

Bind a query prefix to the CDA namespace

XPath 1.0 states that an unprefixed QName in a node test has a null namespace URI; the XML document's default xmlns declaration is not used for that query name.[3] The reliable correction is to bind a prefix in the XPath evaluation context and use it for CDA elements.

/cda:ClinicalDocument/cda:component/cda:structuredBody
  /cda:component/cda:section/cda:title

The query prefix is chosen by the query. The source document does not need to use the same prefix, or any prefix at all. The important mapping is:

cda → urn:hl7-org:v3

For example, a browser-based XPath 1.0 evaluation can supply a resolver:

const namespaces = {
  cda: 'urn:hl7-org:v3',
  sdtc: 'urn:hl7-org:sdtc'
};

const resolver = prefix => namespaces[prefix] || null;

const result = xmlDoc.evaluate(
  '//cda:section/cda:title',
  xmlDoc,
  resolver,
  XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
  null
);

If the expression contains cda: but the resolver does not define it, the processor should report an unresolved prefix or expression error rather than treating it as the document's default namespace.

XPath versions

XPath 2.0 and 3.1 can define a default element namespace

Later XPath versions include a default element/type namespace in the static expression context. An unprefixed element name test can use that namespace when the host language or processor configures it.[4] This behaviour is not a reason to assume that every XPath environment will interpret //section as CDA.

XPath 3.1 also supports URI-qualified names such as:

//Q{urn:hl7-org:v3}section/Q{urn:hl7-org:v3}title

This form states the URI directly and avoids a separate prefix mapping, but an XPath 1.0 processor will not recognise it. Record the XPath version and host-language behaviour as part of the interface configuration.

Extensions

CDA documents can contain more than one namespace

The CDA core model uses urn:hl7-org:v3 for base CDA elements and also identifies elements in extension namespaces such as urn:hl7-org:sdtc.[1] A document can also contain locally defined or implementation-guide-specific extensions.

<ClinicalDocument
    xmlns="urn:hl7-org:v3"
    xmlns:sdtc="urn:hl7-org:sdtc"
    xmlns:ext="urn:example:clinical-extension">
  <id root="2.16.840.1.113883.999.1"/>
  <sdtc:statusCode code="active"/>
  <ext:processingNote>Synthetic example</ext:processingNote>
</ClinicalDocument>

Each namespace needs its own query mapping when you need to select its elements:

//cda:id
//sdtc:statusCode
//ext:processingNote

Do not treat every prefixed element as invalid CDA or silently treat every extension as a base CDA element. Confirm the applicable CDA implementation guide and extension rules before deciding whether the extra namespace is permitted.

Diagnostic fallback

Use local-name() to investigate, not as the default query strategy

A namespace-agnostic expression can confirm that matching local names exist:

//*[local-name() = 'section']

This is useful when the namespace is unknown or unexpectedly redeclared. However, it can match section elements from CDA, an extension vocabulary or a namespace-free fragment. That can hide the underlying namespace error and select the wrong data.

If a temporary diagnostic query must restrict the namespace, include both parts of the expanded name:

//*[local-name() = 'section'
    and namespace-uri() = 'urn:hl7-org:v3']

A properly bound cda:section expression is shorter and normally clearer for production mappings.

Failure patterns

What common namespace failures look like

Observed resultLikely causeWhat to verify
//ClinicalDocument returns nothingThe query looks in no namespace while the document uses urn:hl7-org:v3.Root element namespace URI and XPath prefix mapping.
//cda:section reports an expression errorThe XPath context does not define the cda prefix.Namespace resolver or static namespace declarations.
Elements are found but attributes are missingUnprefixed attributes were queried with a namespace prefix.Use @root, @code or @value unless the attribute itself is prefixed.
A query works on one CDA but not anotherThe expression depends on the source's visible prefix or a namespace is redeclared lower in the tree.Compare namespace URIs at the exact failing nodes.
local-name() returns too many nodesDifferent vocabularies use the same local element name.Add namespace-uri() or return to explicit prefix mappings.
A text diff reports widespread changesPrefixes or namespace declaration locations changed even though many expanded names remain equivalent.Compare namespace-aware structure as well as serialized text.
An extension element is ignoredOnly the base CDA namespace was configured.Applicable implementation guide and required extension namespace mappings.

Troubleshooting

A repeatable namespace investigation

  1. Parse the original XML without rewriting it. Start from the exact synthetic payload that produces the failure.
  2. Check for a parser error first. Namespace investigation assumes the document is well-formed XML.
  3. Inspect the root expanded name. Record both the root local name and namespace URI.
  4. Inspect namespace declarations in scope. Include declarations on ancestors and any redeclarations near the failing element.
  5. Identify the XPath version. Confirm whether the processor follows XPath 1.0 or supports a configured default element namespace.
  6. Bind a query prefix explicitly. Map cda to urn:hl7-org:v3 and update each CDA element name test.
  7. Handle attributes separately. Leave ordinary unprefixed CDA attributes unprefixed in the query.
  8. Add extension mappings only when needed. Use the exact URI from the document and confirm it is permitted by the applicable profile.
  9. Use local-name() only to isolate the fault. Replace diagnostic wildcards with namespace-aware expressions before release.
  10. Retest equivalent serializations. Confirm that default, cda: and alternative prefixes bound to the same URI produce the same logical selection.

Use the CDA & Clinical XML Viewer to inspect a synthetic document's namespace-aware tree, then use the CDA & Clinical XML Diff Tool to compare structural changes between two namespace variations.

Checklist

What to define in a CDA XML mapping

  • The CDA version and implementation guide being processed.
  • The expected root local name and namespace URI.
  • The XPath version and namespace configuration supported by the runtime.
  • A stable query-prefix map for CDA and each permitted extension vocabulary.
  • Which attributes are unprefixed and which genuinely belong to another namespace.
  • How unknown extension elements are logged, ignored, rejected or preserved.
  • Whether comparisons are textual, namespace-aware or schema-aware.
  • Tests using equivalent prefixes and intentional namespace mismatches.
  • A rule that prevents namespace-agnostic selectors from silently entering production.
  • Synthetic regression documents with no patient data or confidential identifiers.

FAQ

Frequently asked CDA namespace questions

Why does //ClinicalDocument return no results?

The CDA element normally belongs to urn:hl7-org:v3, while an unprefixed XPath 1.0 name test looks for an element in no namespace. Bind a query prefix to the CDA namespace and use //cda:ClinicalDocument.

Must the document use the cda prefix?

No. The document can use a default namespace, cda: or another prefix. Namespace-aware processing compares the resolved URI and local name, not the visible prefix text.

Should CDA attributes use the cda prefix in XPath?

Usually not. Ordinary attributes such as root, extension, code and value are normally unprefixed and therefore in no namespace. Query them as @root or @code.

Is local-name() safe for production mappings?

It can be, but it discards the namespace distinction unless paired with namespace-uri(). A prefixed namespace-aware name test is normally clearer and less likely to match extension elements accidentally.

Why does the same XPath work in one product but fail in another?

The products may support different XPath versions or configure the default element namespace differently. Compare the XPath version, static namespace context and explicit prefix mappings rather than only the expression text.

Advertisement

Primary references

CDA, XML namespace and XPath sources

  1. HL7 CDA Core: ClinicalDocument logical model: the CDA ClinicalDocument XML namespace and extension-namespace examples.
  2. W3C Namespaces in XML 1.0, Third Edition: expanded names, namespace declarations, prefix bindings, scope, default namespaces and unprefixed attributes.
  3. W3C XML Path Language (XPath) Version 1.0: node tests, namespace expansion and the null namespace used for unprefixed QNames.
  4. W3C XML Path Language (XPath) Version 3.1: default element/type namespaces, expanded QNames and URI-qualified name tests.

Local CDA implementation guides, extension rules, schema packages and processing agreements remain authoritative for the document types accepted by a specific interface.