Provides an object layer for reading and writing XML documents.  The Mondrian XML-Object Mapping layer generates a class for each entity in an XML schema, a member property for each attribute, collections for sub-objects, and methods to serialize to and from XML.

 

Revision $Id: //guest/julian_hyde/mondrian/src/main/mondrian/xom/package.html#1 $
Copyright (C) Copyright 2001-2002 Kana Software, Inc.
Author Dan Sommerfield, Julian Hyde

Schema format

The schema is defined in an XML file, whose format is somewhat similar to an XML Schema.  The (self-describing) meta-schema is meta.xml (as you can see, an XSL style-sheet formats each schema into a javadoc-like web page).

Other schemas include mondrian.xml and resource.xml

Generated Java Classes

The utilities in this package enable conversion of XML (stored in a DOM-style model) into a typesafe Java representation. Roughly, conversion occurs as follows:

Converting an XML Document to its XOM representation is a two-step process. First, you parse the XML into a DOM representation using your favorite W3C DOM Level 1-compliant parser (note: MSXML is supported as well for backward compatibility). Then, you instantiate the XOM {@link mondrian.xom.ElementDef} subclass corresponding to the root element in the document, passing a portion of the DOM as input to the constructor. After this, the fully-constructed root element provides complete typesafe access to the whole document!

Specific instructions for parsing using a DOM-compliant parser (such as XERCES):

  1. Instantiate your parser, parse the document (validation against the DTD is optional), and retrieve the parsed {@link org.w3c.dom.Document} object.
  2. Call {@link org.w3c.dom.Document.getDocumentElement()} to retrieve the toplevel Node in the document.
  3. Wrap the toplevel node in an instance of {@link mondrian.xom.wrappers.W3CDOMWrapper}.
  4. Construct the appropriate {@link mondrian.xom.ElementDef} subclass from the wrapped node.

Specific instructions for parsing using Microsoft's XML Parser:

  1. Instantiate your parser, parse the document (validation against the DTD is optional), and retrieve {@link com.ms.xml.om.Document} object representing the document.
  2. Call {@link com.ms.xml.om.Document#getRoot()} to retrieve the toplevel Element in the document.
  3. Wrap the toplevel element in an instance of {@link mondrian.xom.wrappers.MSXMLWrapper}.
  4. Construct the appropriate {@link mondrian.xom.ElementDef} subclass from the wrapped node.

Generator

The utility is the Java class {@link MetaGenerator}. It takes command-line arguments; usage:

jview <classpath_options> mondrian.xom.MetaGenerator
	[-debug] [-test]
	<XML model file> <output directory>
The XML model file is the name of the XML model file to use (e.g. assoc.xml, input.xml, etc).  You would have something like 'diablo.xml'.

The output directory is the directory in which all output files (a DTD and a .java file to be precise) will be created.  Note that the actual names of these files are specified by the dtdName, className, and packageName attributes of the <Model>.

Given mondrian.xml as follows:

<Model
    name="bas"
    dtdName="mondrian.dtd"
    className="MondrianDef"
    packageName="mondrian.olap"
    root="Schema"
    version="1.0">
...
A run generates mondrian.dtd and {@link mondrian.olap.MondrianDef}:
$ cd das
$ jview mondrian.xom.MetaGenerator src/main/mondrian/olap/mondrian.xml src/main
Writing src/main/mondrian/olap/mondrian.dtd
Writing src/main/mondrian/olap/MondrianDef.java
Done
$

todo: There is now an ANT target, XOMGen, implemented by {@link mondrian.xom.XOMGenTask}.

Tester

There is another helpful utility we use to verify that the stuff we generate works.  It is class {@link MetaTester}, and you invoke it as follows:

jview <classpath_options> mondrian.xom.MetaTester [-debug]
        [-msxml | -xerces] <XML model file> <output dir> [<tests>...]
All the arguments are the same as the ones for {@link MetaGenerator}, except for tests.  <tests> is a list of test .xml files that should be valid according to the generated DTD.  The tester will validate the java files against the DTD and also against the java class.  It also runs some basic checks on the java class to make sure that it works.

We run both utilities from a test harness in the mining directory.  Look at any of the runtest.sh files under the mining/test/metamodel/<anydir> hierarchy.  These files ultimately call down to a common script file.  The test script runs {@link MetaGenerator}, compiles the generated java class (to verify that it was created correctly), tests one or more test xml files against the model, and optionally installs the generated files into the build tree (it was easier to generate the files and check them in than to run MetaGenerator with each build).  The package declaration "Broadbase.mining.xml" is added to any java classes when they get installed.  Also, the test harness diffs the generated DTD and .java file against the most recently generated version.

Currently the test harness tests all files against both the MSXML parser and against the Apache XERCES parser.

Generation

For all XML files except meta.xml, we generate corresponding DTD and NameDef.java at build time.  {@link MetaDef} is tricky, because it depends upon itself.  We source-control it and meta.dtd.  If you change meta.xml, you need to regenerate them as follows:
$ p4 edit src/main/mondrian/xom/meta.dtd src/main/mondrian/xom/MetaDef.java
$ build metadef

Then insert the modified class files into lib/boot.jar. If things get screwed up, refresh MetaDef.java and meta.dtd from perforce.

Guidelines for writing models

  1. Note that within an <Entity>, all <Attribute>s must occur before all <Object>, <Array> or <CData> elements.

Known Issues

Dependencies

This package is dependent upon the following other packages:

Class {@link XOMGenTask} only is dependent upon {@link org.apache.tools.ant}. You therefore require ant.jar to build, but not to run.

Class {@link mondrian.xom.wrappers.XercesDOMParser} only is dependent upon {@link org.xml.sax} and {@link org.apache.xerces.parsers.DOMParser}. You therefore require xerces.jar to build, but not to run.