Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it okay to use invalid XHTML 1.0 Strict for its benefits?

Tags:

html

xml

xhtml

I have been making my web-pages use invalid XHTML 1.0 Strict for the benefits of custom entities in my webpages, as well as other extensibility features.

Are there any issues in doing this, or is this a perfectly valid way to write web pages (other than the inability to be displayed in browsers that don't understand the XHTML mime type)?

I am curious if I can push this to wrap bootstrap div hell of my own web pages into meaningful tags using XML technology without the use of javascript to parse custom tags.

In particular, it is very difficult to write valid XHTML because a lot of HTML5 tags such as canvas and nav are not defined as valid elements, and has a lot of strange ways to become invalid despite valid modern web practices. This is even more of an issue since this makes it impossible to use AngularJS directives to create custom tags, or use custom tags to parse using javascript(Since I don't know how to extend the existing XHTML doctype to make it understand those tags to be valid).

Example:

index.php:

<?php header('Content-Type: application/xhtml+xml'); ?>
<!-- Not intended to be validated, but exploit XHTML benefits anyway -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml-strict.dtd"
[
    <!ENTITY page-title "Daily Bits and Bytes">
]>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <title>&page-title;</title>
  </head>
  <body>
  </body>
</html>

Consideration:

I am considering dropping strict doctype altogether and instead just use my own doctype and send the webpage as application/xhtml+xml. To my understanding, XHTML DTD is not even looked at by modern browsers, and XHTML does not offer any extra entities/definitions that HTML doesn't have by default, so it seems to add no value to the webpage, whereas custom entities do.

eg:

<?php header('Content-Type: application/xhtml+xml'); ?>
<!DOCTYPE my-dtd
[
    <!ENTITY page-title "Daily Bits and Bytes">
]>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>&page-title;</title>
  </head>
  <body>
  </body>
</html>

Another benefit

Example, creating a custom color attribute for p tag:

index.xhtml:

<?xml-stylesheet type="application/xml" href="style.xsl"?>
<!DOCTYPE my-dtd
[
    <!ENTITY page-title "Daily Bits and Bytes">
]>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>&page-title;</title>
  </head>
  <body>
    <p color="blue">This paragraph is blue</p>
    <p>hello</p>
  </body>
</html>

style.xsl:

<xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xhtml="http://www.w3.org/1999/xhtml">                
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>   

<xsl:template match="xhtml:p[@color]">  
  <xsl:element name="xhtml:p">
    <xsl:attribute name="style">
    color: 
    <xsl:value-of select="./@color" />
    ;
    </xsl:attribute>
    <xsl:apply-templates select="@*|node()" />
  </xsl:element>  
</xsl:template>  
</xsl:stylesheet>

One more benefit

Custom domain specific elements, eg navigation-bar,

turning

<navigation-bar>
  <link to="someplace">text</link>
</navigation-bar>

to

<nav class="navbar navbar-inverse">
  <ul class="nav navbar-nav>
    <li><a href="someplace">text</a></li>
  </ul>
</nav>

without javascript(still makes page load slower but once the production is over, you can just optimize away the xsl by only serving the transformation results, which is easier than translating jquery/javascript based transformations).

index.xhtml:

<?xml-stylesheet type="application/xml" href="style.xsl"?>
<!DOCTYPE my-dtd
[
    <!ENTITY page-title "Daily Bits and Bytes">
]>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>&page-title;</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
  </head>
  <body>
    <navigation-bar>
      <link to="https://stackoverflow.com">StackOverflow</link>
      <link to="https://facebook.com">Facebook</link>
      <link to="https://twitter.com">Twitter</link>
    </navigation-bar>
    <p color="blue">I am red</p>
    <p>hello</p>
  </body>
</html>

style.xsl:

<xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xhtml="http://www.w3.org/1999/xhtml">                
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>

<xsl:template match="xhtml:p[@color]">  
  <xsl:element name="xhtml:p">
    <xsl:attribute name="style">
    color: 
    <xsl:value-of select="./@color" />
    ;
    </xsl:attribute>
    <xsl:apply-templates select="@*|node()" />
  </xsl:element>  
</xsl:template>  

<xsl:template match="xhtml:navigation-bar">
  <xsl:element name="nav">
    <xsl:attribute name="class">navbar navbar-inverse</xsl:attribute>
    <xsl:element name="ul">
      <xsl:attribute name="class">nav navbar-nav</xsl:attribute>
      <xsl:for-each select="current()/xhtml:link">
        <li>
          <xsl:element name="a">
            <xsl:attribute name="href">
              <xsl:value-of select="@to" />
            </xsl:attribute>
            <xsl:value-of select="text()" />
          </xsl:element>

        </li>
      </xsl:for-each>
    </xsl:element>
  </xsl:element>
</xsl:template>
</xsl:stylesheet>
like image 578
Dmitry Avatar asked Jan 22 '26 19:01

Dmitry


1 Answers

No, however...

My entire platform uses XHTML5, that is HTML5 + the XML parser (application/xhtml+xml). There is always a valid way to do code strictly and achieve your goals. See the link in my profile for my site. You can still use everything XHTML / XML along with HTML5. You're lucky I saw this, most people bash XHTML because of the poor path the W3C was going with XHTML 2.0. You'll have to use the not-a-doctype-doctype and you'll be required to still use the XML declaration.

Also you're not doing content negotiation correctly. You need to serve pages as application/xhtml+xml only when the client's user agent explicitely declares support for it. In example IE7's $_SERVER['HTTP_ACCEPT'] header is *.* which total BS because IE7 doesn't support squat-diddly. Also if a client's browser doesn't support application/xhtml+xml then you shouldn't serve the XML declaration (which also triggers quirks mode in older versions of IE).

   if (isset($_SERVER['HTTP_ACCEPT']) && stristr($_SERVER['HTTP_ACCEPT'],'application/xhtml+xml'))
   {
    header('Content-Type: application/xhtml+xml; charset=UTF-8');
    echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";
   }

Make sure that the browser's web development tools (usually "Net" for network requests) show the main page as having a application/xhtml+xml media type/mime/type.

like image 93
John Avatar answered Jan 24 '26 09:01

John