Self-closing tags in XML files Self-closing tags in XML files xml xml

Self-closing tags in XML files


See the W3C specs for XML and XHTML:

It depends on the Element Type declaration

An element with no content is said to be empty. The representation of an empty element is either a start-tag immediately followed by an end-tag, or an empty-element tag.

but also

Empty-element tags may be used for any element which has no content, whether or not it is declared using the keyword EMPTY. For interoperability, the empty-element tag SHOULD be used, and SHOULD only be used, for elements which are declared EMPTY.

This means, when your DTD contains something like

<!ELEMENT img EMPTY>

you should use

<img/>

unless you have good reason to use

<img></img>

Note that SHOULD is defined in RFC2119 as

This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.

If you are working with XML that does not have a DTD or Schema, you can also influence how the XML is serialized with a predefined libxml constant:

LIBXML_NOEMPTYTAG (integer): Expand empty tags (e.g. <br/> to <br></br>)

But note that this option is currently just available in the functions DOMDocument::save and DOMDocument::saveXML, so you cannot use it with SimpleXml.


Yes, it's not as simple as it seems at first.

XSD differences:

First of all, it depends on your data type. If you use an XSD schema definition, which defines the types of your elements, then <element></element> can actually only be used for string types. Because, that's what it is, it is actually an empty string value: "".

Therefore, it is illegal to use <element></element> for an integer, while by contrast <element/> is applicable for all simple types.

JAXB differences:

JAXB (Java XML Binding) has similar quirks. It would map <element/> as different values depending on the target data type:

  • for String, it would be a ""
  • for Integer, it would be a 0.
  • for other types, it would just skip it.

You could be tempted to think that <element/> would resolve to a null value. But you actually need to use <element xsi:nil="true"/> for that. Which I have never ever seen in practice.

HTML:

In HTML there is always that third option of <element> without closing tag. I don't know about you, but several times a day, I have to remind myself that HTML isn't just XML. And that actually means that <br> and <br/> aren't the same thing. You shouldn't use <br/> in HTML, and you shouldn't use <br> in XHTML.

Angular 2+:

But what I really wanted to get to, continuing on the last statement, if you use frameworks like Angular2+ there is another thing to keep in mind.

Without diving too much in detail, Angular replaces custom HTML tags with HTML templates which are linked to components. However it only supports the <element></element> format. You're not allowed to use the <element/> format.

I personally try to avoid the <element/> syntax, because it has all the potential to make things go wrong. (= bad aji).


When you want to use PHP's xml parser, you can specify actions upon a start tag, close tag, or a complete tag. Based upon your wishes, you might want to have an action specifically on the close tag.