package require tdom
dom parse {
<html>
<body>
<a href="http://somewhere.com/foo.html">Link</a>
</body>
</html>
} doc
$doc selectNodes //a
i.e. it returns exactly one domNode
However if I change to XHTML (stripped back for ease of posting)
dom parse {
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<body>
<a href="http://somewhere.com/foo.html">Link</a>
</body>
</html>
} doc
then the selectNodes doesn't return anything. How should I change the
selectNodes call to "Do What I Mean"?
Thanks,
Alan
the difference is you have now defined a default namespace in your
root element, so you no longer have an node whose name is "a".
I do not know then tdom interface, but there should be a way to
define a defauilt namepsace, or define a prefix something like
xmlns:xhtml="http://www.w3.org/1999/xhtml"
then selectNodes //xhtml:a should work. I assume the tdom docs
will show exactly how to do this.
Bruce
following up on my own comment ;)
perusing the tdom docs the selectNodes command takes -namespaces
option to specify a list of prefix namespace pairs so the command
would be
$doc selectNodes -namespaces {ns1 "http://www.w3.org/1999/xhtml"} //ns1:a
(that is one lien the my newsreader is wrapping
or, if you are doing many selectNodes on the same document
there is the selectNodesNamespaces method to define the
prefixes once for all calls to selectNodes on that document
Bruce
Thanks Bruce,
I was desperately trying to specify sensible things on the -namespaces
flag without adding a prefix to the tag in the xpath query.
Can anyone more knowledgeable about the tDom interface chip in to say
how to define a default namespace so that I can continue to search for
//a rather than, say, //foo:a?
Alan
Maybe try the default namespace prefix:
$doc selectNodes -namespaces {"" "http://www.w3.org/1999/xhtml"} //a
Never tried it, but "" is the prefix for the default namespace.
In general, it isn't uncommon to deal with this issue: you can't force
everyone to use the same prefix for the given namespace, or to use the
default prefix exactly where you want it. So you are going to have to
figure out the mapping somehow (that is why XML has prefix mappings).
Thanks for the suggestion Tom, but I'm afraid it doesn't work. I'd
expect there to be something in tDom to define the default namespace
URI. Is there a guru in the house who can tell me what it is, or,
definitively, that there isn't anything?
--
Alan
That's too bad, I ran into the same chicken-n-egg issue when writing
an xslt for WSDL files. You have to establish the prefix->namespace
mappings for externally produced documents, but I always used
something besides the default.
$doc selectNodesNamespaces {xhtml http://www.w3.org/1999/xhtml}
$doc selectNodes //xhtml:a
The selectNodesNamespaces method of the documents set the namespace
resolution for any selectNodes call further for this document or nodes
of it. Lesser tedious then giving -namespaces, but that works too.
In XPath 1.0, every not prefixed element name selects only not
namespaced elements. If you want to match a namespaced element, use a
prefix, bound to that namespace. This all is XPath 1.0, as stated by
the rec, nothing special to tdom. If you want to match a namespaced
node with XPath you've to use a prefix for it, even if the node, you
want to match has his namespace from the default one. See XSLT 1.0 for
another example. The sense behind this is, that if every not prefixed
element name in an XPath expression would be in a default namespace,
how could you then mix namespaced and not namespaced elements in one
query?
rolf
$doc selectNodes -namespaces {"" "http://www.w3.org/1999/xhtml"} //a
> In XPath 1.0, every not prefixed element name selects only not
> namespaced elements. If you want to match a namespaced element, use a
> prefix, bound to that namespace. This all is XPath 1.0, as stated by
> the rec, nothing special to tdom.
Are you sure that Xpath 1.0 explicitly prohibits that the above
expression
work? Or do you assume it vaguely from context?
I have found two relevant paragraphs in the RFC:
2.3 Node Tests
...
A node test can have the form NCName:*. In this case, the prefix is
expanded in the same way as with a QName, using the context namespace
declarations. It is an error if there is no namespace declaration for
the prefix in the expression context. The node test will be true for
any node of the principal type whose expanded-name has the namespace
URI to which the prefix expands, regardless of the local part of the
name.
5 Data Model
...
Some types of node also have an expanded-name, which is a pair
consisting of a local part and a namespace URI. The local part is a
string. The namespace URI is either null or a string. The namespace
URI specified in the XML document can be a URI reference as defined in
[RFC2396]; this means it can have a fragment identifier and can be
relative. A relative URI should be resolved into an absolute URI
during namespace processing: the namespace URIs of expanded-names of
nodes in the data model should be absolute. Two expanded-names are
equal if they have the same local part, and either both have a null
namespace URI or both have non-null namespace URIs that are equal.
Do these paragraphs explicitly prohibit the above mentioned option? Is
there another paragraph
that states it more clearly?
> The sense behind this is, that if every not prefixed
> element name in an XPath expression would be in a default namespace,
> how could you then mix namespaced and not namespaced elements in one
> query?
I cannot understand this explanation. I see two options:
1- If you want to mix namespaced and not namespaced elements in the
same query, do NOT use: -namespaces {"" "http://www.w3.org/1999/
xhtml"}
2- If you do NOT want to mix namespaced and not namespaced elements
in the
same query, you have the OPTION to use -namespaces {"" "http://
www.w3.org/1999/xhtml"}
Where is the problem?
Well, the original poster asked how to do something (selecting
namespaced elements with an XPath 1.0 expression) and I showed, how
this is done.
Since you don't claim, that it doesen't work as I said, I take this
as confirmation: it works, as I showed (in fact it does).
>> In XPath 1.0, every not prefixed element name selects only not
>> namespaced elements. If you want to match a namespaced element, use a
>> prefix, bound to that namespace. This all is XPath 1.0, as stated by
>> the rec, nothing special to tdom.
>
>Are you sure that Xpath 1.0 explicitly prohibits that the above
>expression
>work? Or do you assume it vaguely from context?
Yes, I'm sure that the XPath 1.0 expression "//a" never matches a
namespaced element, with a pure XPath 1.0 engine.
It's of course not prohibited, to dream of an XPath 1.0 engine plus
something (and a bit rmmadwim).
And it's not, that XPath 1.0 absolutely had to be, as it is. XPath 2.0
does some things in another way, than 1.0.
But just because, you think something would be more cleaner or more
convenient or would fit your brain model better doesn't mean, that the
XPath 1.0 recommendation group decided this way.
If someone knows XPath 1.0 (say, because of XSLT 1.0) then it is
the natural way, to prefix every namespaced element in an XPath 1.0
expression.
>I have found two relevant paragraphs in the RFC:
>
>[...]
>
>Do these paragraphs explicitly prohibit the above mentioned option? Is
>there another paragraph
>that states it more clearly?
The relevant text is just a few lines above your first citation:
A QName in the node test is expanded into an expanded-name using the
namespace declarations from the expression context. This is the same
way expansion is done for element type names in start and end-tags
except that the default namespace declared with xmlns is not used: if
the QName does not have a prefix, then the namespace URI is null [...]
Lemme repeat: "if the QName does not have a prefix, then the namespace
URI is null".
This all, of course, could not stop you from wanting it work also in
another way. Though, not talking of ramifications, that's not done in
a blink.
rolf