Re: SXPath namespaces
"Dmitry Lizorkin" <[email protected]> Fri, 12 May 2006 14:41:30 +0400
| Newsgroups | gmane.lisp.scheme.ssax-sxml |
|---|---|
| Message-ID | <[email protected]> |
Hi,
Please excuse me for the delayed answer to your question.
Since your SXML document contains a namespace-id in element names, a namespace prefix occuring in the XPath node test should be mapped to that namespace-id for obtaining the result we expect, i.e:
((sxpath "my:schema" '[(my . "xsd")])
doc)
==>
((xsd:schema))
Please note that (unlike XPath 2.0) the XPath 1.0 Specification implemented in sxpath does not support a default namespace declaration in node tests: in subsect. 2.3 of the XPath 1.0 Specification, it is stated that "..if the QName [in the node test] does not have a prefix, then the namespace URI is null (this is the same way attribute names are expanded)." You thus _have to_ use a prefix in an XPath name test for addressing a
named node from a non-null namespace URI; i.e. your code
(sxpath "schema" '[...])
selects the 'schema child element (from a null namespace) regardless of the namespace binding supplied as the second argument.
Since "XPath is a language for _addressing_ parts of an XML document", the result produced by the `sxpath' function for an XPath location path is a nodeset consisting of nodes in _exactly_ the same form (by `eq?') as in the original SXML document. You thus have no way of converting the '(xsd:schema) element into a '(schema) or '(my:schema) element in pure XPath. If you want your result to be returned in a different form, you can apply queries/transformations to it afterwards. For example, you can remove the "xsd:" prefix from all the nodes in the nodeset by using pre-post-order transformations:
(pre-post-order
'((xsd:schema))
`((*text* . ,(lambda (tag text) text))
(*default*
. ,(lambda (tag . content)
(cons
(if
(equal?
(sxml:name->ns-id tag) ; produces either #f or a string
"xsd")
(string->symbol (sxml:ncname
(list tag) ; a node is required as an argument
))
tag)
content)))))
==>
((schema))
Note however that new SXML nodes are essentially constructed as a result of such a transformation; these new nodes are physically different from the ones from the original SXML document.
Regards,
Dmitry
----- Original Message -----
From: Victor Morilla Padial
To: [email protected]
Sent: Tuesday, May 09, 2006 1:42 AM
Subject: [ssax-sxml] SXPath namespaces
Hi,
Given the following code:
(define doc
'(*TOP*
(@
(*NAMESPACES*
(xsd "http://www.w3.org/2001/XMLSchema")))
(*PI* xml "version=\"1.0\" encoding=\"UTF-8\"")
(xsd:schema)))
(pretty-print ((sxpath "my:schema" '[(my . "http://www.w3.org/2001/XMLSchema")]) doc))
(pretty-print ((sxpath "schema" '[(#f . "http://www.w3.org/2001/XMLSchema")]) doc))
(pretty-print ((sxpath "xsd:schema" '[(xsd . "http://www.w3.org/2001/XMLSchema")]) doc))
I spected the result:
((my:schema))
((schema))
((xsd:schema))
But the real result is:
(())
(())
(())
What am I doing wrong? What's the correct way to deal with namespaces using SXPath
Thanks in advance,
VĂctor Morilla