Using DOM 3 functionality from Java

The latest Batik SVN has support for DOM Level 3 Core and Events. However, JDKs < 1.5 include the DOM 2 interfaces and this can cause problems when trying to use the DOM 3 versions of these same interface files (org.w3c.dom). Though the concrete Batik DOM classes implement the DOM 3 functionality, you won't be able to access those methods through the org.w3c.dom interfaces.

There are two ways to overcome this problem. The first is to install the DOM Level 3 interfaces using the Endorsed Standards Override Mechanism. Copy the file lib/xml-apis-dom3.jar into the endorsed standards override directory and the DOM 3 interfaces will be visible. You can then write code against them (for example, call Document.renameNode directly). However, this will mean that other people cannot run or compile your code unless they have JDK 1.5 or they have also installed the xml-apis-dom3.jar in the same way.

The second method, which requires less messing about with the JDK, is to cast your DOM objects to the concrete Batik DOM objects and call your DOM 3 methods directly on them. The Batik DOM classes are in the org.apache.batik.dom package. The classes named "Abstract*" implement the DOM interfaces, and also contain the DOM 3 methods. The advantage of this method is that for your code to compile and run in others' environments, they need not mess around with the endorsed standards overrides.

An example:

  import org.apache.batik.dom.AbstractDocument;
  import org.apache.batik.dom.svg.SVGDOMImplementation;
  import org.w3c.dom.DOMImplementation;
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;

  public class C {
      public void f() {
          // Create a new SVG document
          DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
          Document doc = impl.createDocument("http://www.w3.org/2000/svg", "svg", null);

          // Create a 'g' element and append it to the root 'svg' element
          Element e = doc.createElementNS("http://www.w3.org/2000/svg", "g");
          doc.getDocumentElement().appendChild(e);

          // Cast the document object to org.apache.batik.dom.AbstractDocument,
          // so that DOM 3 methods will be guaranteed to be visible
          AbstractDocument document = (AbstractDocument) doc;

          // Now a DOM 3 method can be used
          document.renameNode(e, "http://www.w3.org/2000/svg", "text");
      }
  }

For cases where the DOM Level 3 versions of these interfaces contain constants that you wish to use, the constants have been copied into the Batik DOM classes. For example:

  import org.apache.batik.dom.AbstractNode;
  import org.apache.batik.dom.svg.SVGDOMImplementation;
  import org.w3c.dom.DOMImplementation;
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;

  public class C {
      public void f() {
          // Create a new SVG document
          DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
          Document doc = impl.createDocument("http://www.w3.org/2000/svg", "svg", null);

          // Create a 'g' element and append it to the root 'svg' element
          Element svg = doc.getDocumentElement();
          Element e = doc.createElementNS("http://www.w3.org/2000/svg", "g");
          svg.appendChild(e);

          AbstractNode n1 = (AbstractNode) svg;
          AbstractNode n2 = (AbstractNode) e;
          int position = n1.compareDocumentPosition(n2);
          if (position == AbstractNode.DOCUMENT_POSITION_PRECEDING
                        | AbstractNode.DOCUMENT_POSITION_CONTAINS) {
              System.out.println("The svg element contains the g element.");
          } else {
              System.out.println("Something is wrong!");
          }
      }
  }

Note that using these org.apache.batik.dom interfaces is only needed for the DOM 3 Core and DOM 3 Events interfaces. There were no earlier versions of the DOM XPath interfaces to conflict with, so these can be used directly (org.w3c.dom.xpath).

Of course, none of this matters if you are just using the DOM 3 functionality in ECMAScript, as the matter of interfaces is hidden from the scripting environment.

  • No labels