[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> </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