XPath rule template for HTML

Hello everyone,

I hope you are all doing well.

We have been using SonarQube successfully for several years and truly value the product and its continuous evolution. I would like to share some feedback regarding the HTML rule set, based on our experience in a long-running project.

In our project, we build user interfaces using XHTML. During analysis, these files are evaluated using the HTML ruleset, which works well in general. However, we have repeatedly encountered situations where important best‑practice or quality rules appear to be missing. A few examples:

  • <label> elements should only be used with a corresponding for attribute

  • <img> tags should always define an alt attribute

  • HTML pages should inherit from the project’s base template rather than being created independently

There are more similar cases where project‑ or organization‑specific conventions would benefit greatly from rule-based validation.

We fully understand that implementing custom rules individually for customers would not be feasible. However, many teams like ours could help themselves if there were a way to define custom rules. For XML files, SonarQube already provides a very powerful XPath-based rule template, which we have found extremely useful.

Would it be possible to provide a similar XPath rule template for HTML as well? This would give teams more flexibility, allow them to enforce accessibility and architectural conventions, and further increase the value of the HTML analysis.

Thank you very much for considering this suggestion, and for your ongoing work on SonarQube.

Best regards,
Andreas Igel

1 Like

Hi Andreas,

I am very happy to hear you are getting good value of the HTML analysis :partying_face:
And thank you for your nice feedback :wrapped_gift:

Do you think you could share a few examples of where you would expect issues being raised in XHTML and they are not being raised?

I’d also be interested in hearing more of how you’re using XPath.

Hi Gabriel,

thank you for answering on it. I can provide some examples:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
  xmlns:p="http://primefaces.org/ui"
  xmlns:h="http://xmlns.jcp.org/jsf/html"
  xmlns:f="http://xmlns.jcp.org/jsf/core"
  template="/resources/templates/basetemplate.xhtml"
  xmlns:custom="http://xmlns.jcp.org/jsf/composite/composite">

  <ui:define name="headextension">
    <f:metadata>
      <f:viewParam name="id" value="#{baseManagedBean.id}" />
    </f:metadata>
  </ui:define>

  <ui:define name="content">
    <div class="card">
      <h5>Basic</h5>
      <p:inputText />

      <h5>Floating Label</h5>
      <span class="ui-float-label">
        <p:inputText id="float-input" value="#{inputTextView.text}" />
        <p:outputLabel for="@previous" value="Username" />
      </span>

      <h5>Left Icon</h5>
      <span class="ui-input-icon-left">
        <i class="pi pi-search" />
        <p:inputText placeholder="Search" />
      </span>

      <h5>Help Text</h5>
      <div class="field">
        <p:outputLabel styleClass="block">Username</p:outputLabel>
        <p:inputText id="username1" styleClass="block" />
        <small class="block">Enter your username to reset your password.</small>
      </div>

      <h5>Disabled</h5>
      <p:inputText disabled="true" />

      <h5>Image-Examples</h5>
      <div class="card">
        <p:graphicImage name="images/nature/nature4.jpg" library="demo" />
        <p:graphicImage name="images/nature/nature5.jpg" library="demo" alt="A picture" />
      </div>
    </div>
  </ui:define>
</ui:composition>

Possible regex for checks would be:

  • //*[local-name()=‘outputLabel’ and namespace-uri()=‘http://primefaces.org/ui’ and not(@for)]
    
  • //*[local-name()=‘graphicImage’ and namespace-uri()=‘http://primefaces.org/ui’ and not(@alt)]
    
  • //*[local-name()=‘composition’ and namespace-uri()='http://xmlns.jcp.org/jsf/facelets' and not(@template)]
    

When checking this with online xpath-checks, of course there are problems which might make trouble to your XPath-library:

  • tagnames are camel case
  • in html there are self-closing elements

But this might could be solved by a preprocessing of html/xhtml to replace findings of /> or to lower tag-names.

Thank you for having a look on that.

Best regards,

Andreas

1 Like