Chapter 4. Handling namespaces

Namespaces are such a common part of todays XML that it is worth introducing them sooner rather than later. The input document simply adds the namespace declaration to the document element as shown in Example 4.1, “An input document with a namespace”. No other changes are needed (which is as it should be).

Example 4.1. An input document with a namespace


<?xml version="1.0" encoding="utf-8" ?>
<doc xmlns="http://www.dpawson.co.uk/ns#">   1
<chapter id="c1">
  <title>chapter title</title>
  <para>Chapter content</para>
</chapter>

<chapter id="c2">
<title>chapter title</title>
<para>xx</para>
<para>yy</para>
<para>zz</para>
</chapter>

<chapter id="c3">
  <para>Invalid first child of chapter</para>
  <title>chapter title</title>
  <para>xx</para>
  <para>yy</para>
  <para>zz</para>
</chapter>
</doc>
  

1

The document element is now namespaced. The namespace is inherited by all its children


When it comes to the Schematron file, there are quite a few changes to be made. Example 4.2, “The Schematron file using namespaces” shows the changes. Additionally I've removed the report element counting the number of paragraphs to improve the output readability.

Example 4.2. The Schematron file using namespaces


<?xml version="1.0" encoding="iso-8859-1"?>
<iso:schema    xmlns="http://purl.oclc.org/dsdl/schematron" 
	       xmlns:iso="http://purl.oclc.org/dsdl/schematron" 
	       xmlns:sch="http://www.ascc.net/xml/schematron"
	       xmlns:dp ="http://www.dpawson.co.uk/ns#"
	       queryBinding='xslt2'
	       schemaVersion="ISO19757-3">
  <iso:title>Test ISO schematron file. Introduction mode </iso:title>

  <iso:ns prefix="dp" uri="http://www.dpawson.co.uk/ns#" />  1


<iso:pattern id="doc.checks">
  <iso:title>checking an XXX document</iso:title>
  <iso:rule context="dp:doc">
                                                                  2
    <iso:report test="dp:chapter">Report date.<iso:value-of 
             select="current-dateTime()"/></iso:report>
    <iso:assert test="count(dp:chapter) = 3"
                 >There should be 3 chapters only</iso:assert>
  </iso:rule>
</iso:pattern>

  <iso:pattern id="chapter.checks">
    <iso:rule context="dp:chapter">
      <iso:assert test="dp:title">Chapter should have  a title</iso:assert>
      <iso:assert test="count(dp:para) >= 1">A chapter must have one or more paragraphs</iso:assert>
      <iso:assert test="*[1][self::dp:title]">Title must be first child of chapter</iso:assert>
      <iso:assert test="@id">All chapters must have an ID attribute</iso:assert>
    </iso:rule>
  </iso:pattern>
</iso:schema>

  

1

This is how the namespace is declared in the Schematron file

2

And all the tests must use this namespace prefix!


Note that the context and test attributes both now refer to the namespace by its prefix, which is declared in the ns element near the top of the file. Running this provides the output as in Example 4.3, “The resultant output”

Example 4.3. The resultant output


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<svrl:schematron-output xmlns:dp="http://www.dpawson.co.uk/ns#"   1
                        xmlns:xs="http://www.w3.org/2001/XMLSchema"
                        xmlns:svrl="http://purl.oclc.org/dsdl/svrl"
                        xmlns:sch="http://www.ascc.net/xml/schematron"
                        xmlns:iso="http://purl.oclc.org/dsdl/schematron"
                        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                        title="Test ISO schematron file. Introduction mode "
                        schemaVersion="ISO19757-3">
   <svrl:ns-prefix-in-attribute-values uri="http://www.dpawson.co.uk/ns#" 
                                                      prefix="dp"/> 2
   <svrl:active-pattern name="doc.checks" id="doc.checks"/>
   <svrl:fired-rule context="dp:doc"/>
   <svrl:successful-report test="dp:chapter">
      <svrl:text>Report date.2007-01-20T16:21:23.135Z</svrl:text>
   </svrl:successful-report>
   <svrl:active-pattern name="chapter.checks" id="chapter.checks"/>
   <svrl:fired-rule context="dp:chapter"/>
   <svrl:fired-rule context="dp:chapter"/>
   <svrl:fired-rule context="dp:chapter"/>
   <svrl:failed-assert test="*[1][self::dp:title]">                    3
      <svrl:text>Title must be first child of chapter</svrl:text>
   </svrl:failed-assert>
</svrl:schematron-output>

  

1

The namespace and prefix are appended to the document element

2

The prefix and namespace are made available for further processing if needed

3

All assertions are described in terms of the namespaced source document.


I left the one remaining error in there to show that there is no change (other than the reported test attribute values). I hope you'll agree, a little more complicated, but no big deal if you are used to using namespaces.

Legal Notice