[REBOL] Re: Navigation in output produced by parse-xml
From: joel:neely:fedex at: 1-Jun-2001 7:22
Hi, James,
My cut-and-paste mistake! My hat is off to you!!!
James Carlyle wrote:
> I used your code samples but got an error with the print-path
> function. My xml looked like '<a><b>1</b><b>2</b></a>'.
I hit the panic button when I saw your post, because I am
fairly obsessive about posting code either from a console
transcript or from cut-and-pasted from an editor window
(precisely because of typos, etc.) I was SURE that I had
done so in this case, and had momentary images of impending
Alzheimers'...
> I went through you code as thoroughly as my knowledge of
> Rebol would allow, and I think the problem is that the _walk
> function is passing a block instead of a block of blocks to
> the print-path function, so the 'rejoin ["/" first item]'
> section fails because the second item processed is 'none'.
> The first time that print-path is called, the block passed
> is '["a" none [["b" none ["1"]] ["b" none ["2"]]]]'.
>
Your analysis of the bug is EXACTLY correct, but the but is
in the outdated copy of WALKXML that I had pasted at the top
of the email! The corrected-while-writing version is
8<------------------------------------------------------------
walkxml: func [
xmlb [block!]
sel [any-function!]
doer [any-function!]
/local _walk parents
][
parents: copy []
_walk: func [xel [block!]] [
insert/only parents xel
if do [sel parents] [do [doer parents]]
if found? third xel [
foreach item third xel [
if block? item [_walk item]
]
]
remove parents
]
_walk first third xmlb
exit
]
8<------------------------------------------------------------
The correction consisted of changing the first line in the body
of _WALK to use the /ONLY refinement to preserve each ancestor
reference as a whole block reference, rather than appending the
components of the ancestor individually.
I also had placed an EXIT at the end of WALKXML since the value
returned from _WALK wasn't meaningful.
Using the *corrected* version of WALKXML, along with your data,
we get the following transcript:
>> do %walkxml.r
>> any?: func [estack [block!]] [true]
>> print-path: func [estack [block!] /local str] [
[ str: copy ""
[ foreach item estack [
[ insert str rejoin ["/" first
item]
[
]
[ print str
[ ]
>> walkxml parse-xml "<a><b>1</b><b>2</b></a>" :any? :print-path
/a
/a/b
/a/b
>>
I apologize for the confusion!!!
> The only problem with asking for help is that you have be
> clever enough to understand the answers :-)
>
<grumble at="self">
The only problem with cut-and-paste is that you have to be
clever enough to replace what you pasted earlier if you
find a bug...
</grumble>
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com