RelaxNG, Entities, and Namespaces

I ran into a couple of roadblocks in trying to use entities with Mallard recently, and thought I would share how I worked around them in case anyone else needed to do the same thing. Although my examples deal with Mallard, what I note here will also work for entities in DocBook 5 documents, or any other RelaxNG-based XML documents.

Entities?

Before I start, though, if anyone is wondering what I'm talking about when I say, "entities," they are a handy variable-like feature of XML and a couple of other markup languages. For example, they allow you to type something like &exaile; into your document, and then have it magically parsed as:

The final, rendered result would be a familiar GUI click-path like, "Click Applications > Multimedia > Exaile." While entities have their limitations and are not ideal for all use-cases, they serve a purpose. This web page gives a good overview of entities and how to use them.

Using Entities in Mallard / RelaxNG documents

To set up and use entities in your XML-based document, you basically need three things. You need a file that contains the entities you want to use*, you need to declare where those entities are tracked, and you need to actually use the entities in your document.

The Entities File

Previously, step one was very easy. You would just create a file that contained values like this:

However a somewhat recent change in libxml** prevents these entities from being parsed as they used to be, making things slightly more involved. (If you've been bitten by this bug, libxml will throw up a, "Namespace default prefix was not found" error message.) To resolve this, you need to include the relevant XML namespace in the entity. For Mallard-based documents, the resulting changes look like this:

Out of the Woods

Once you make it past step one, the rest is a walk in the park.

Step two is to declare your entities in the start of your documentation files. I modified a DocBook 5 example to come up with this:

Wrapping Things Up

Step three, using your entities in your documents, is no different than what you would have done with DocBook 4 or any other XML-based syntax. For example, typing &abiword; will be parsed as:

and will cause "Application > Office > Abiword," to magically appear in your rendered documentation.

If you have any questions, corrections, or suggestions (as I'm sure you're all keen to be chatting about XML entities), feel free to leave me a note in the comments.

* I'm using external entities, which requires a separate file, but you can also use named or charater entities.

** Apparently the namespace of the parent node is no longer inherited by the entities, so you need to declare the namespace in the entity itself.