[MarkLogic Dev General] Quirks of generating xhtml with xquery

Michael Blakeley michael.blakeley at marklogic.com
Thu Aug 28 10:16:48 PDT 2008


Yes, it's namespaces - good hunch.

In your html element, xmlns="..." is a default element namespace 
declaration. It applies to both XML and XPath expressions within that 
scope, so $options/title in the enclosed expression is is identical to 
$options/xhtml:title, which matches nothing.

A simple fix is to move the XPath expression outside the scope of the 
default element namespace declaration:

define function display:html($options as element(options))
as element(xhtml:html)
{
   let $title as xs:string := $options/title
   return <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <title>{ $title }</title>
      </head>
      ...
    </html>
}

As a debugging technique, you could also have tried $options/*:title - 
the asterisk matches any namespace. However, this technique is perilous: 
you might match a:title when you wanted b:title. If you do want both 
kinds of title, it's less error-prone to write 'a:title|b:title'. As a 
code review practice, I recommend looking for and rewriting any uses of 
'*:' that sneak into your XQuery.

-- Mike

Eric Palmitesta wrote:

> Secondly, I followed your example, approximately.  I have a function 
> which returns an element(xhtml:html), which xhtml is declared as the 
> namespace "http://www.w3.org/1999/xhtml".  The root node is <html 
> xmlns="http://www.w3.org/1999/xhtml">.  I pass into this function an 
> <options> element, containing for example a <title>.
> 
> define function display:html($options as element(options))
> as element(xhtml:html)
> {
>    <html xmlns="http://www.w3.org/1999/xhtml">
>      <head>
>        <title>{ $options/title/text() }</title>
>      </head>
>      ...
>    </html>
> }
> 
> Probably a namespace problem than anything else, but the title text 
> isn't rendered, as if the $options variable wasn't even there.  Suggestions?
> 
> --
> 
> Thirdly, thanks for all the great responses, everyone, you've given me 
> much to read (on the mailing list and external links).  Much appreciated!
> 
> Eric
> 
> Michael Blakeley wrote:
>> Eric,
>>
>> I think it's important to distinguish between server behavior and 
>> browser behavior. While we can use XQuery to generate valid XHTML on the 
>> server, the browser may decide to interpret it as quirky HTML tag-soup. 
>> This is commonly known as "quirks mode" (vs "standards compliance mode" 
>> - apologies if you already know all this), and Mozilla-family browsers 
>> will tell you which mode was used for the current page (on Firefox 3, 
>> Tools > Page Info).
>>
>> In my experience, it's best to avoid quirks mode by persuading the 
>> browser to render in standards-compliance mode: that is, tell the 
>> browser to expect XHTML. When I combine the XHTML doctype with the xhtml 
>> namespace, I find that I don't need any special tricks with <textarea/> 
>> elements. Here's an example:
>>
>> xquery version "1.0";
>>
>> declare variable $ACCEPT-XML as xs:boolean :=
>>   (: Opera says that it accepts xhtml+xml, but does not. :)
>>   contains(xdmp:get-request-header('accept'), 'application/xhtml+xml')
>>     and not(contains(xdmp:get-request-header('user-agent'), 'Opera'))
>> ;
>>
>> xdmp:set-response-content-type( concat(
>>   if ($ACCEPT-XML) then "application/xhtml+xml" else "text/html",
>>   "; charset=utf-8") ),
>> '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
>>  "DTD/xhtml1-transitional.dtd">',
>> <html xmlns="http://www.w3.org/1999/xhtml">
>>   <head>
>>     <title>test</title>
>>   </head>
>>   <body>
>>     <textarea></textarea>
>>   </body>
>> </html>
>>
>> Some of the above code was lifted from cq/lib-controller.xqy - cq is 
>> itself a moderately complex XQuery + XHTML + JavaScript application, and 
>> while its code isn't always as clean as I might like, it hopefully 
>> provides some useful examples. All of the cq source code is open under 
>> the Apache license.
>>
>> -- Mike
>>
>> Eric Palmitesta wrote:
>>> Aaron and I discussed this briefly at the training seminar, but I'd 
>>> like to get a sense of what other developers are doing to get around 
>>> the quirks of generating xhtml with xquery (rather than a java 
>>> servlet/jsp based website which pulls records from MarkLogic via 
>>> XDBC/XCC.
>>>
>>> One such quirk: Childless elements with no internal nodes and an 
>>> explicit closing tag are automatically folded into elements with no 
>>> closing tag.  <div></div>, which is valid xhtml, will become <div /> 
>>> after being processed by MarkLogic (breaks visual representation).  
>>> Some better examples are <script ...></script> and 
>>> <textarea></textarea>, which are expected to contain no internal nodes 
>>> in xhtml.
>>>
>>> I've taken to writing things like
>>>
>>> <script ... >{" "}</script>
>>>
>>> or
>>>
>>> <textarea>&nbsp;</textarea>
>>>
>>> which successfully preserves the explicit closing tag, keeping xhtml 
>>> happy.  Is there a more elegant way to do this?
>>>
>>> Are there other banana-peels I should watch out for when generating 
>>> xhtml with xquery?  Is creating an entire website by generating xhtml 
>>> with xquery generally frowned upon, or accepted?  Admittedly, it seems 
>>> less flexible than a <web language>-based site, however the xdmp 
>>> namespace seems to provide sufficient functionality, and transforming 
>>> xml data into xhtml is incredibly easy with xquery.
>>>
>>> Cheers,
>>>
>>> Eric
>>>
>>>
>>> PS
>>> My vocabulary might be incorrect regarding words like 'tag' and 
>>> 'node', please correct me if necessary.
>>>
>>> PPS
>>> I can see the archives at 
>>> http://xqzone.marklogic.com/pipermail/general/ but are they 
>>> searchable?  I have a feeling newcomers such as myself will be prone 
>>> to asking questions which have already been discussed at length.
>>> _______________________________________________
>>> General mailing list
>>> General at developer.marklogic.com
>>> http://xqzone.com/mailman/listinfo/general
>> _______________________________________________
>> General mailing list
>> General at developer.marklogic.com
>> http://xqzone.com/mailman/listinfo/general
> _______________________________________________
> General mailing list
> General at developer.marklogic.com
> http://xqzone.com/mailman/listinfo/general



More information about the General mailing list