Skip to main content
XMLDir

Search 309 pages — tools, formats, elements, namespaces, directory, comparisons, XPath, datatypes, glossary, parse errors, schema errors, use cases, blog and product.

Document syntax

General entity

An entity declared with <!ENTITY name "text"> whose replacement text is substituted wherever &name; appears in content.

General entities are the macro facility of XML. Declared in the internal subset or an external DTD, they let a document define a name once — a product name, a boilerplate paragraph, a repeated identifier — and reference it throughout.

Whether the replacement text is spliced into the tree or left as a reference is a parser setting, and that has consequences most people never see coming. Our pipeline leaves it as a reference: an element built inside an entity is not addressable by XPath, while the string value of its parent still contains the entity's text. Canonicalization, which has no such option, expands it.

Defined in
XML 1.0 §4.2
Category
Document syntax
Also written
internal entity, <!ENTITY>

Shown, not asserted

All 4 claims are executed on every test run, against the same engines the tools use. If the behaviour changes, the test fails rather than this page quietly becoming wrong.

  • An element that arrives through an entity is not addressable — the reference was never substituted into the tree.

    document.xml
    <!DOCTYPE x [<!ENTITY sig "<who>Ada</who>">]>
    <x>&sig;</x>
    expression
    count(//who)

    What the engine returns

    0
  • Yet the string value of the parent contains the entity's text all the same.

    document.xml
    <!DOCTYPE x [<!ENTITY sig "<who>Ada</who>">]>
    <x>&sig;</x>
    expression
    string(/x)

    What the engine returns

    Ada
  • Canonicalization has no such setting: it expands the entity and drops the DOCTYPE.

    document.xml
    <!DOCTYPE x [<!ENTITY sig "<who>Ada</who>">]>
    <x>&sig;</x>

    What the engine returns

    c14n
    <x><who>Ada</who></x>
    
  • Entities may reference other entities, and the chain is resolved.

    document.xml
    <!DOCTYPE x [<!ENTITY inner "world"><!ENTITY outer "hello &inner;">]>
    <x>&outer;</x>
    expression
    string(/x)

    What the engine returns

    hello world

What catches people out

  • Whether an entity is substituted into the tree or kept as a reference node is a parser option — libxml2 calls it --noent. Code that walks children sees different documents under each setting.
  • Because replacement text is parsed, an entity containing an unbalanced tag fails at the point of reference rather than of declaration.
  • An entity may not reference itself, directly or through a chain.
  • Consumers that reject DOCTYPE for security reasons reject your entities with it. For interchange, expand them before publishing.

Get started

Bring order to the XML your team can't afford to ignore.

Create a free account and get a private workspace to search, validate, diff, and monitor your XML feeds, sitemaps, schemas, and vendor integrations.