Re: xhtml errors

Rich Bowen <[email protected]> Sat, 30 May 2026 10:25:39 -0400
Newsgroups gmane.comp.apache.documentation
Message-ID <[email protected]>
Ok, I think that this is because in my changes to make stuff more =
mobile-friendly, I introduced HTML5 stuff.

The build system generates HTML with an XHTML 1.0 Strict DOCTYPE and
validates using DTD-based XML validation. The actual output already uses
HTML5 features (aria-* attributes, inline SVG, modern content models in
<button>), causing validate-xhtml to fail on every generated page.

I think the solution is the below, but proposing it here for sanity =
check before YOLO=E2=80=99ing it, because it=E2=80=99s a significant =
change.

The below patch:
1. Switches the output method from "xml" to "html" and emits
   <!DOCTYPE html> instead of the XHTML 1.0 Strict DOCTYPE.
2. Replaces the Ant <xmlvalidate> target with vnu.jar (W3C Nu HTML
   Checker) for HTML5 validation.
3. Removes xml:lang from <html> elements (redundant in HTML5; lang=3D
   suffices).
4. Removes the XHTML namespace from common.xsl (not needed for HTML
   output method).


=3D=3D=3D 1. style/xsl/language.xsl =E2=80=94 output method and doctype =
=3D=3D=3D

The xsl:output element is generated dynamically by language.xsl for each
per-language stylesheet. Currently sets method=3D"xml" and emits XHTML =
1.0
Strict public/system identifiers.

Switch to method=3D"html" and use the "about:legacy-compat" system =
identifier,
which is the W3C-blessed way to emit a valid HTML5 DOCTYPE from XSLT 1.0
processors. Browsers treat
  <!DOCTYPE html SYSTEM "about:legacy-compat">
identically to <!DOCTYPE html>.
See: https://www.w3.org/TR/html5/syntax.html#the-doctype

If your XSLT processor emits a bare <!DOCTYPE html> without
doctype-system (xsltproc does), you can omit it entirely. Test locally.

--- a/docs/manual/style/xsl/language.xsl
+++ b/docs/manual/style/xsl/language.xsl
@@ -408,10 +408,7 @@
     <xsl:element name=3D"xsl:output">
         <xsl:attribute name=3D"method">
             <xsl:choose>
-            <xsl:when test=3D"$type =3D 'manual' or
-                            $type =3D 'chm' or
-                            $type =3D 'zip'">
-                <xsl:text>xml</xsl:text>
+            <xsl:when test=3D"$type =3D 'manual'">
+                <xsl:text>html</xsl:text>
             </xsl:when>
             <xsl:otherwise>
                 <xsl:text>text</xsl:text>
@@ -444,17 +441,5 @@
         </xsl:attribute>
         <xsl:attribute name=3D"indent">no</xsl:attribute>
-        <xsl:if test=3D"$type =3D 'manual' or
-                      $type =3D 'chm' or
-                      $type =3D 'zip'">
-            <xsl:attribute name=3D"doctype-public">
-                <xsl:text>-//W3C//DTD XHTML 1.0 Strict//EN</xsl:text>
-            </xsl:attribute>
-        </xsl:if>
-        <xsl:if test=3D"$type =3D 'manual'">
-            <xsl:attribute name=3D"doctype-system">
-                <xsl:text>http://www.w3.org/TR/xhtml1/DTD/</xsl:text>
-                <xsl:text>xhtml1-strict.dtd</xsl:text>
-            </xsl:attribute>
-        </xsl:if>
-        <xsl:if test=3D"$type =3D 'chm' or
-                      $type =3D 'zip'">
-            <xsl:attribute =
name=3D"omit-xml-declaration">yes</xsl:attribute>
-        </xsl:if>
+        <xsl:if test=3D"$type =3D 'manual'">
+            <xsl:attribute =
name=3D"doctype-system">about:legacy-compat</xsl:attribute>
+        </xsl:if>
     </xsl:element>


=3D=3D=3D 2. style/xsl/common.xsl =E2=80=94 remove XHTML namespace =3D=3D=3D=


With method=3D"html", elements should be in no namespace (plain HTML).

--- a/docs/manual/style/xsl/common.xsl
+++ b/docs/manual/style/xsl/common.xsl
@@ -27,3 +27,3 @@
 <xsl:stylesheet version=3D"1.0"
               xmlns:xsl=3D"http://www.w3.org/1999/XSL/Transform"
-                  xmlns=3D"http://www.w3.org/1999/xhtml">
+                  xmlns=3D"">


=3D=3D=3D 3. All page-type XSL files =E2=80=94 remove xml:lang =3D=3D=3D

Remove xml:lang=3D"{$doclang}" from <html> elements. The lang=3D =
attribute
alone is sufficient in HTML5.

--- a/docs/manual/style/xsl/manualpage.xsl
+++ b/docs/manual/style/xsl/manualpage.xsl
@@ -32 +32 @@
-<html xml:lang=3D"{$doclang}" lang=3D"{$doclang}">
+<html lang=3D"{$doclang}">

Same one-line change in:
  - indexpage.xsl (line 51)
  - faq.xsl (line 32)
  - directiveindex.xsl (line 32)
  - moduleindex.xsl (line 32)
  - overrideindex.xsl (line 39)
  - sitemap.xsl (line 32)
  - quickreference.xsl (line 32)
  - synopsis.xsl (line 33)


=3D=3D=3D 4. build/build.xml =E2=80=94 replace validate-xhtml target =3D=3D=
=3D

Replace <xmlvalidate> with the W3C Nu HTML Checker (vnu.jar).
Download: https://github.com/validator/validator/releases

--- a/docs/manual/build/build.xml
+++ b/docs/manual/build/build.xml
@@ -121,7 +121,17 @@
 <target name=3D"validate-xhtml" description=3D"- validates all (X)HTML =
result files">
-    <xmlvalidate lenient=3D"false" failonerror=3D"false" warn=3D"true">
-        <xmlcatalog refid=3D"w3c-catalog" />
-        <fileset dir=3D"../" includes=3D"**/*.html.*">
-            <patternset refid=3D"scratch" />
-        </fileset>
-    </xmlvalidate>
+    <!-- HTML5 validation using W3C Nu HTML Checker (vnu.jar).
+         Download from https://github.com/validator/validator/releases
+         and place in build/ or set vnu.jar property. -->
+    <property name=3D"vnu.jar" value=3D"vnu.jar" />
+    <echo message=3D"Validating HTML5 with Nu HTML Checker..." />
+    <apply executable=3D"java" failonerror=3D"false" parallel=3D"true"
+           maxparallel=3D"50">
+        <arg value=3D"-jar" />
+        <arg value=3D"${vnu.jar}" />
+        <arg value=3D"--skip-non-html" />
+        <fileset dir=3D"../" includes=3D"**/*.html.*">
+            <patternset refid=3D"scratch" />
+        </fileset>
+    </apply>
 </target>


=3D=3D=3D SUMMARY =3D=3D=3D

Files to modify:
  - docs/manual/style/xsl/language.xsl      (output method + doctype)
  - docs/manual/style/xsl/common.xsl        (default namespace)
  - docs/manual/style/xsl/manualpage.xsl    (xml:lang removal)
  - docs/manual/style/xsl/synopsis.xsl     (xml:lang removal)
  - docs/manual/style/xsl/indexpage.xsl    (xml:lang removal)
  - docs/manual/style/xsl/faq.xsl          (xml:lang removal)
  - docs/manual/style/xsl/directiveindex.xsl (xml:lang removal)
  - docs/manual/style/xsl/moduleindex.xsl    (xml:lang removal)
  - docs/manual/style/xsl/overrideindex.xsl  (xml:lang removal)
  - docs/manual/style/xsl/sitemap.xsl       (xml:lang removal)
  - docs/manual/style/xsl/quickreference.xsl (xml:lang removal)

And in the build tree:

  - docs/manual/build/build.xml             (validate-xhtml target)

New dependency:
  - vnu.jar (W3C Nu HTML Checker) for build-time validation

Generated output changes (before/after):

  BEFORE:
    <?xml version=3D"1.0" encoding=3D"UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns=3D"http://www.w3.org/1999/xhtml" lang=3D"en" =
xml:lang=3D"en">

  AFTER:
    <!DOCTYPE html SYSTEM "about:legacy-compat">
    <html lang=3D"en">

Side effects of method=3D"html":
  - No XML declaration (<?xml ...?>) =E2=80=94 good, it triggered quirks =
mode
    in old IE anyway
  - Void elements use <br> <hr> <meta ...> <img ...> instead of
    <br/> <hr/> <meta .../> <img .../> =E2=80=94 correct HTML5
  - No xmlns attribute on <html> =E2=80=94 correct HTML5

Rendering impact: Zero. All modern browsers already treated the XHTML
Strict pages in standards mode, same as HTML5.


=3D=3D=3D TESTING =3D=3D=3D

1. Apply patch, rebuild one language: ./build.sh en
2. Inspect generated .html =E2=80=94 verify DOCTYPE is HTML5
3. Run: java -jar vnu.jar --skip-non-html ../bind.html.en.utf8
4. Confirm void elements are not self-closed (<br> not <br/>)
5. Spot-check pages render identically in browser