foreach fn [$docroot selectNodes /a/b/c/d\[@name="filename"\]] {
set fullname [$fn text]
...
Now, some of my xml files have "Filename" where they meant "filename".
(bl%dy fortran programmers...)
As I dont know much about xpath and its various versions/dialects, can
anybody suggest a solution?
Yours,
pdev.
The great thing about using XPath inside a general-purpose
programming language like Tcl (as opposed to, say, XSLT) is
that anything that's impossible or inconvenient to express
in XPath can be kicked out into the application code:
Just change this:
| foreach fn [$docroot selectNodes {/a/b/c/d[@name="filename"]}] {
| set fullname [$fn text]
| ...
| }
to this:
| foreach fn [$docroot selectNodes {/a/b/c/d}] {
| if {[string tolower [domNode $fn getAttribute "name"]] eq "filename"} {
| set fullname [$fn text]
| ...
| }
| }
--Joe English
There aren't various XPath versions/dialects. There is one w3c
recommendation, XPath 1.0, and another in work, the currently not
finished XPath 2.0. That's it. Though, most implementations allow to
add or have additional XPath functions (tDOM also does; you could add
your own additional XPath functions implemented in tcl).
If it's just, that you want to match both "filename" and "Filename"
and didn't like the good advice, Joe has already given, a pure XPath
solution would be
foreach fn [$docroot selectNodes {/a/b/c/d[@name="filename" or @name="Filename"]} {
...
}
rolf
This observation is sound and worth to be repeated.
>Just change this:
>
>| foreach fn [$docroot selectNodes {/a/b/c/d[@name="filename"]}] {
>| set fullname [$fn text]
>| ...
>| }
>
>to this:
>
>| foreach fn [$docroot selectNodes {/a/b/c/d}] {
>| if {[string tolower [domNode $fn getAttribute "name"]] eq "filename"} {
>| set fullname [$fn text]
>| ...
>| }
>| }
That mixes the node command mode and the node token mode, both
supported by tDOM (the [domNode $fn getAttribute ..] versus [$fn text]
syntax). In general this isn't a good idea. Use the one or the other
mode for the nodes of one document. Another detail is, that the
getAttribute method raises error, if the searched attribute isn't
found. There is an optional argument, which is returned, if the
requested attribute isn't present. That two points together makes:
foreach fn [$docroot selectNodes {/a/b/c/d}] {
if {[string tolower [$fn getAttribute "name" ""]] eq "filename"} {
set fullname [$fn text]
...
}
}
rolf