so

QT4 grammar explorer

Volume 10, Issue 6; 04 Feb 2026

A quick hack to make exploring the QT4CG grammars a little easier.

[This is a bonus markup post to make up for the fact that I missed #MarkupMonday last week. (I’m not sure that’s really true, but I’m claiming it anyway.)]

What happened was, I was trying to work out how a particular XPath expression was being parsed. It wasn’t raising an error, but it also wasn’t giving me an answer that I understood. I went to the XPath specification and started trying to explore the grammar. It’s perfectly possible, but it seemed awkward.

The XPath grammar (and the XQuery, and XSLT Pattern grammars) are stored in XML. That means it’s easy to process them with XSLT. So I spent 20 minutes building a web of HTML pages from the productions. Then I realized it would be really handy if the grammar pages could link back to the places in the specifications where those productions are described. All the specifications are also XML, so that’s also easy.

The result is the grammar explorer.

My initial cut was, like most of my web design, functional but a little ugly. Many thanks to Juri Leino for putting in a fair bit of effort to improve the results!

The question I was trying to answer, if you’re curious, was why does this:

<literal attr="{Q{http://example.com/}local}"/>

produce

<literal attr=""/>

In case you want to think about it for a moment, I’ll put in a spoiler break.


 #####                                      
#     # #####   ####  # #      ###### ##### 
#       #    # #    # # #      #      #    #
 #####  #    # #    # # #      #####  #    #
      # #####  #    # # #      #      ##### 
#     # #      #    # # #      #      #   # 
 #####  #       ####  # ###### ###### #    #
                                            
    ######                                  
    #     # #####  ######   ##   #    #     
    #     # #    # #       #  #  #   #      
    ######  #    # #####  #    # ####       
    #     # #####  #      ###### #  #       
    #     # #   #  #      #    # #   #      
    ######  #    # ###### #    # #    #     

In the interest of full disclosure, I didn’t solve this with the grammar explorer. In the end, frustrated, I loaded up Saxon in a debugger, put a break point in the code for processing attribute value templates, and just looked at the result.

It’s obvious, in hindsight, that

<literal attr="{Q{http://example.com/}local}"/>

is the same as:

<literal attr="{child::Q{http://example.com/}local}"/>

That’s why it’s the empty string. Had there happened to be a child element with the right name, I’d have got a different answer. Whether that would have been more or less confusing is an open question.

#XML #XQuery #XSLT

Please provide your name and email address. Your email address will not be displayed and I won’t spam you, I promise. Your name and a link to your web address, if you provide one, will be displayed.

Your name:

Your email:

Homepage:

Do you comprehend the words on this page? (Please demonstrate that you aren't a mindless, screen-scraping robot.)

What is eight plus three?   (e.g. six plus two is 8)

Enter your comment in the box below. You may style your comment with the CommonMark flavor of Markdown.

All comments are moderated. I don’t promise to preserve all of your formatting and I reserve the right to remove comments for any reason.