[xquery-talk] Generating xhtml from xml in no namespace
Michael Blakeley
michael.blakeley at marklogic.com
Wed Dec 17 06:51:10 PST 2008
Andrew,
I don't like the '*:foo' shortcut either - it's nice for debugging, but
it's a red flag when I'm doing code reviews.
The empty-namespace problem is much easier to work around than the
earlier responses imply. The trick is to understand that every XPath
expression evaluates in the current scope's default element namespace,
but you can control the scope's default element namespace.
http://marklogic.markmail.org/search/?q=namespace turns up some similar
discussion threads.
I'll use MarkLogic Server 4.0 with cq as the query interface, and start
with a standalone test case to show the problem:
xquery version "1.0";
declare variable $INPUT as document-node() := document {
<path>
<to><node id="a1">hello andrew</node></to>
</path>,
<path>
<to><node id="a2">hello world</node></to>
</path>
};
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<!-- there should be a span or two here -->
{
for $x in $INPUT/path/to/node
order by $x
return element span { text { $x } }
}
</body>
</html>
=>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<!-- there should be a span or two here -->
</body>
</html>
The result includes no spans, because $INPUT/path/to/node is looking for
'path' etc in the xhtml namespace. Now let's try my preferred technique
- a function call. This test will use a local function, but we could
also use a library function. Either way, the function body starts with
the same default element namespace as the XQuery module scope.
xquery version "1.0";
declare variable $INPUT as document-node() := document {
<path>
<to><node id="a1">hello andrew</node></to>
</path>,
<path>
<to><node id="a2">hello world</node></to>
</path>
};
declare function local:get-nodes()
as element(node)+
{
$INPUT/path/to/node
};
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<!-- there should be a span or two here -->
{
for $x in local:get-nodes()
order by $x
return element span { text { $x } }
}
</body>
</html>
=>
<html xmlns="http://www.w3.org/1999/xhtml">
<body><!-- there should be a span or two here -->
<span>hello andrew</span><span>hello world</span>
</body>
</html>
That works, and it's my preferred solution. But here's another one, if
you don't want to define a function:
...
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<!-- there should be a span or two here -->
{
<dummy xmlns="">{
for $x in $INPUT/path/to/node
order by $x
return element span { text { $x } }
}</dummy>/node()
}
</body>
</html>
=>
<html xmlns="http://www.w3.org/1999/xhtml">
<body><!-- there should be a span or two here -->
<span xmlns="">hello andrew</span><span xmlns="">hello world</span>
</body>
</html>
I'm sure there are other approaches, but those are the two that came to
mind. Hope that helps.
-- Mike
On 2008-12-17 06:08, Andrew Welch wrote:
> Yeah I saw that, thanks, but it's not really a reasonble solution...
> (in my humble opinion)
>
> I will go with xquery building the input to a transform which
> generates the xhtml, which is probably a nicer solution than using
> just xquery anyway.
>
> I was going to say that generating xhtml should be the #1 use case,
> but I guess using it in that way wasn't really expected?
>
>
>
> 2008/12/17 Jesper Tverskov<jesper.tverskov at gmail.com>:
>> I guess a wild card prefix would do as explained in my tutorial
>> "Creating XHTML with XQuery", http://www.xmlplease.com/xquery-xhtml.
>>
>>
>> for $x in collection(...)/*:path/*:to/*:node
>>
>>
>> Cheers,
>>
>> Jesper Tverskov
>> http://www.xmlplease.com
>> _______________________________________________
>> talk at x-query.com
>> http://x-query.com/mailman/listinfo/talk
>>
>
>
>
More information about the talk
mailing list