Namespaces

Suppose instead of the simple custom vocabulary I’ve been using so far, you wanted to use the standard MathML presentation vocabulary as shown in Example 14.4.

Example 14.4. A MathML document containing the first three Fibonacci numbers

<?xml version="1.0"?>
<mathml:math xmlns:mathml="http://www.w3.org/1998/Math/MathML">
  <mathml:mrow>
    <mathml:mi>f(1)</mathml:mi>
    <mathml:mo>=</mathml:mo>
    <mathml:mn>1</mathml:mn>
  </mathml:mrow>
  <mathml:mrow>
    <mathml:mi>f(2)</mathml:mi>
    <mathml:mo>=</mathml:mo>
    <mathml:mn>1</mathml:mn>
  </mathml:mrow>
  <mathml:mrow>
    <mathml:mi>f(3)</mathml:mi>
    <mathml:mo>=</mathml:mo>
    <mathml:mn>2</mathml:mn>
  </mathml:mrow>
</mathml:math>

The biggest change from the previous examples is that MathML uses namespaces on all the elements. The basic JDOM rule about namespaces is that when an element or attribute is in a namespace, rather than specifying its full qualified name, you give its local name, its prefix, and its URI, in that order. If the element is in the default namespace, omit the prefix. You do not need to add attributes for the namespace declarations. The outputter will figure out reasonable places to put them when the document is serialized.

For example, the following statement creates the root mathml:math element:

Element root = new Element("math", 
                           "mathml", 
                           "http://www.w3.org/1998/Math/MathML");

Example 14.5 demonstrates a complete program that generates MathML from JDOM. The namespace has to be specified on each element. Being a child of an element in the http://www.w3.org/1998/Math/MathML namespace is not sufficient (or necessary) to make the element part of the http://www.w3.org/1998/Math/MathML namespace. Each element (and each attribute) has its own namespace URI which is independent of the other namespace URIs in the document.

Example 14.5. A JDOM program that uses namespaces

import org.jdom.Element;
import org.jdom.Document;
import org.jdom.output.XMLOutputter;
import java.math.BigInteger;
import java.io.IOException;


public class PrefixedFibonacci {

  public static void main(String[] args) {

    Element root = new Element("math", "mathml",
     "http://www.w3.org/1998/Math/MathML");

    BigInteger low  = BigInteger.ONE;
    BigInteger high = BigInteger.ONE;

    for (int i = 1; i <= 5; i++) {

      Element mrow = new Element("mrow", "mathml",
       "http://www.w3.org/1998/Math/MathML");

      Element mi = new Element("mi", "mathml",
       "http://www.w3.org/1998/Math/MathML");
      mi.setText("f(" + i + ")");
      mrow.addContent(mi);

      Element mo = new Element("mo", "mathml",
       "http://www.w3.org/1998/Math/MathML");
      mo.setText("=");
      mrow.addContent(mo);

      Element mn = new Element("mn", "mathml",
       "http://www.w3.org/1998/Math/MathML");
      mn.setText(low.toString());
      mrow.addContent(mn);

      BigInteger temp = high;
      high = high.add(low);
      low = temp;
      root.addContent(mrow);

    }

    Document doc = new Document(root);
    try {
      XMLOutputter serializer = new XMLOutputter("  ", true);
      serializer.output(doc, System.out);
    }
    catch (IOException e) {
      System.err.println(e);
    }

  }

}

Using the default namespace is even easier. Simply specify the namespace on each element but omit the prefix. Example 14.6 demonstrates.

Example 14.6. A JDOM program that uses the default namespace

import org.jdom.Element;
import org.jdom.Document;
import org.jdom.output.XMLOutputter;
import java.math.BigInteger;
import java.io.IOException;


public class UnprefixedFibonacci {

  public static void main(String[] args) {

    Element root = new Element("math", "mathml",
     "http://www.w3.org/1998/Math/MathML");

    BigInteger low  = BigInteger.ONE;
    BigInteger high = BigInteger.ONE;

    for (int i = 1; i <= 5; i++) {

      Element mrow = new Element("mrow", 
       "http://www.w3.org/1998/Math/MathML");

      Element mi = new Element("mi", 
       "http://www.w3.org/1998/Math/MathML");
      mi.setText("f(" + i + ")");
      mrow.addContent(mi);

      Element mo = new Element("mo", 
       "http://www.w3.org/1998/Math/MathML");
      mo.setText("=");
      mrow.addContent(mo);

      Element mn = new Element("mn", 
       "http://www.w3.org/1998/Math/MathML");
      mn.setText(low.toString());
      mrow.addContent(mn);

      BigInteger temp = high;
      high = high.add(low);
      low = temp;
      root.addContent(mrow);

    }

    Document doc = new Document(root);
    try {
      XMLOutputter serializer = new XMLOutputter("  ", true);
      serializer.output(doc, System.out);
    }
    catch (IOException e) {
      System.err.println(e);
    }

  }

}

Although these examples only use a single namespace, you are by no means limited to a single namespace per document in JDOM, any more than you are in XML. Each element can have whatever namespace it requires.


Copyright 2001, 2002 Elliotte Rusty Haroldelharo@metalab.unc.eduLast Modified April 17, 2002
Up To Cafe con Leche