Skip to content

8. Namespaces ​

A coupled run mixes two solvers in one file, each vocabulary in its namespace, coupled.xml:

xml
<?xml version="1.0"?>
<coupled xmlns="https://example.org/flow" xmlns:th="https://example.org/thermal">
  <case name="cavity">
    <dt>1.0e-3</dt>
    <th:case name="plate">
      <th:dt>5.0e-3</th:dt>
      <conductivity xmlns="https://example.org/materials">237.0</conductivity>
    </th:case>
  </case>
</coupled>
f90
program solver
!< Tutorial, chapter 8: namespaces.
use foxy
implicit none
type(xml_file)            :: coupled
integer(I4P), allocatable :: ids(:)
integer(I4P)              :: t

call coupled%parse(filename='coupled.xml')
ids = coupled%find_all(name='{https://example.org/thermal}dt')   ! Clark notation: {namespace}local name
do t=1, coupled%tags_number()
   print '(A)', coupled%name(t)//' -> prefix "'//coupled%prefix(t)//'", local "'//coupled%local_name(t)// &
                '", namespace "'//coupled%namespace(t)//'"'
enddo
print '(A)', 'thermal dt: '//coupled%content(id=ids(1))
t = coupled%find(path='f:coupled/f:case/f:dt', namespaces='xmlns:f="https://example.org/flow"')   ! your own prefixes
print '(A)', 'flow dt:    '//coupled%content(id=t)
t = coupled%find(name='m:conductivity', namespaces='xmlns:m="https://example.org/materials"')
print '(A)', 'k:          '//coupled%content(id=t)
print '(A,I0)', 'literal "dt" matches: ', size(coupled%find_all(name='dt'))       ! names without a map: literal
endprogram solver
  • Names are stored as written (th:dt); prefix, local_name and namespace split and resolve them, on demand: the namespace is the one declared by the nearest xmlns:prefix (or xmlns, for an unprefixed name) up the tree.
  • In find and find_all, {uri}local (Clark notation) matches a local name in a namespace, whatever the prefix the file uses.
  • With namespaces=, declared as in XML, every name of the query uses your prefixes: the file may use others. An unprefixed name then means the default namespace of your map (xmlns="..."), or no namespace if the map has none.
  • Without either, names match literally: dt is only the unprefixed dt.

Running it ​

$ solver
coupled -> prefix "", local "coupled", namespace "https://example.org/flow"
case -> prefix "", local "case", namespace "https://example.org/flow"
dt -> prefix "", local "dt", namespace "https://example.org/flow"
th:case -> prefix "th", local "case", namespace "https://example.org/thermal"
th:dt -> prefix "th", local "dt", namespace "https://example.org/thermal"
conductivity -> prefix "", local "conductivity", namespace "https://example.org/materials"
thermal dt: 5.0e-3
flow dt:    1.0e-3
k:          237.0
literal "dt" matches: 1

What you learned

Match names by namespace with {uri}local or a namespaces= map; namespace(id) tells where a tag belongs. Reference: Namespaces.

Next: 9. Robust input and text.