Registering local DTDs or XML schemas with NetBeans

The NetBeans online help describes the steps for registering a local DTD or XML file with NetBeans' DTDs and XML Schemas Manager. It's succinct and to the point, but for the slow people in the room it's a bit confusing. So here's my tip for registering a local DTD file with NetBeans so that you can use NetBeans' awesome XML validation and completion features.

In my example, I'm trying to use NetBeans to validate an SMF Manifest, which is an XML file defined by a SYSTEM DTD called service_bundle.dtd.1.  On Solaris 10 machines you can find a copy of the DTD file in /usr/share/lib/xml/dtd/service_bundle.dtd.1, and most example SMF manifests that you can find on the Internet include the DOCTYPE like so:

<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">

If you run NetBeans on Solaris 10, I assume this will probably work out-of-the-box (though I haven't tried this...).  However for us hackers on other platforms, you need to copy this file down to your development machine, and then register it with NetBeans so that you can use it.

NetBeans' DTDs and XML Schemas Manager contains a collection of XML Schema Catalogues for a whole bunch of technologies. You'll want to add your local DTDs/Schemas to the User Catalog (sic), which is the only one that's read-write. Do the following:

  1. Tools menu, DTDs and XML Schemas
  2. Choose User Catalog [read-write] from the list of DTDs and XML Schemas
  3. Press "Add Local DTD or Schema..." button
  4. In our example, the DOCTYPE reads:
    SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"
    So, we must map this SYSTEM ID  to a local URI on our development machine.  If it had said PUBLIC "..."
    then we would map a PUBLIC ID instead.
  5. Click the radio button for the relevant ID type (System ID in our case)
  6. Copy in the string ID from your XML file into the relevant field. Make sure you don't put in the double-quotes IMPORTANT: for a DTD that lives on the filesystem ID, like ours, the ID should begin with file:
  7. Click the "Browse..." button and locate the DTD file you downloaded
  8. Click "OK"

You've now mapped the SYSTEM ID to your local copy of the DTD file for service_bundle.dtd. If you try and validate the XML (Alt+Shift+F9, or from the toolbar) it will stop complaining of a missing DTD and actually check your XML against the doctype definition.

I got mislead by the Recommendation (both in the online help and on the dialog box). It says that the "common solution for XML documents specified by DTD is using the Public ID -> URI mapping." It goes on to say that "System ID -> URI mapping can also be used to redirect the DTD location specified by SYSTEM ID", but I got confused by that point.

I also had a hard time working out that the System ID should begin with "file:".  The give-away that I didn't spot until later, was in the error message from the XML validator:

XML validation started.
Checking file:/D:/src/support/smf/emc/manifests/emc-fast-IndexServer.xml...
Referenced entity at "file:/usr/share/lib/xml/dtd/service_bundle.dtd.1".
\usr\share\lib\xml\dtd\service_bundle.dtd.1 (The system cannot find the path specified) [30]
XML validation finished.

Duh!  I could have also just copied that string verbatim. Oh well, now I've blogged about it too, so hopefully I won't forget it next time :)