Search code examples
xsltpattern-matchinghtml-input

Why does `<input pattern="^[^ ]{2,}.*[^ ]$">` trigger "XPath processing error: Binary operator expected"?


I have am XML file with XSL to process it. That works fine using an input element like <input pattern="^[^ ].*[^ ]$">. However when I changed it to <input pattern="^[^ ]{2,}.*[^ ]$">, Firefox ESR 115.3.1 complained:

Fehler beim Laden des Stylesheets: XPath-Verarbeitungsfehler: Binärer Operator erwartet:

(In English (most likely): "Error loading stylesheets: XPath processing error: Binary Operator expected:")

I completely fail to understand how to debug this, what triggers the error, and how to fix it (when I added backslashed before { and }I got a different error message, saying "Invalid character found:").

What makes things harder to understand is that any details (like line, token) are absent in the error message, and when I try to display the source, I only get an empty window.

Almost Minimal Example

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="#default"?>
<xsl:stylesheet id="default" version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:test="test"
        exclude-result-prefixes="xsl test">
  <test:XML>
    <order>
    </order>
  </test:XML>

  <xsl:output method="html" encoding="UTF-8" indent="yes"/>

  <xsl:template match="/xsl:stylesheet">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="xsl:*" /><!-- ignore -->

  <xsl:template match="test:XML/order">
    <html xmlns="http://www.w3.org/1999/xhtml">
      <body>
    <form>
      <input id="customer-name" type="text" name="i.user.name"
         size="25" maxlength="40" placeholder="Name"
         pattern="^[^ ]{2,}.*[^ ]$" required="required" />
    </form>
      </body>
    </html>
  </xsl:template>

</xsl:stylesheet>

Solution

  • XSLT uses curly brackets { and } in attribute values as so called attribute value templates to delimit embedded XPath expressions. So in XSLT, in such attributes, if you want a literal { or }, you need to double them as e.g. {{ and }}, e.g. pattern="^[^ ]{{2,}}.*[^ ]$".