473,549 Members | 2,610 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

TCL/PHP/XML problem: I need to convert an XML file into a TCL list

My TCL proc, XML_GET_ALL_ELE MENT_ATTRS, is supposed to convert an XML
file into a TCL list as follows:

attr1 {val1} attr2 {val2} ... attrN {valN}

This is the TCL code that does this:

[TCL]
set contents [read $fileID [file size ${fileName}.xml]]; close $fileID
if {![string equal $switch -body]} {
# ONLY DO THIS IF THE XML CONTENTS CONTAIN NO BODY - WILL UPGRADE AT
A LATER DATE 11/24/2006 - PHIL
global serverName
if {![info exists serverName]} {
global env
source ./cgi_globals.tcl
global serverName
}

if {[string length [info procs {URL_ENCODE}]] == 0} { source
../url_procs.tcl }; # INCLUDE NEW url_procs.tcl URL TCL LIBRARY
if {[string length [info procs {IS_LIST}]] == 0} { source
{./tcl_string_tool s.tcl} }; # INCLUDE THE TCL STRING LIBRARY CONTAINING
PROC is_list IF !FOUND

# BLOCK TO CREATE THE PHP SCRIPT TO PIPE INTO php.exe
regsub -all {'} [XML_CLEANUP_ATT RIBUTE $contents] {\"}
phpEscapedConte nts
regsub -all {"} $phpEscapedCont ents {\"} phpEscapedConte nts
set php {<? }
append php [subst { if (@is_file("./functions.inc.p hp")) [format %c
123] }]
append php { require_once("./functions.inc.p hp"); }
append php [subst { echo xml_to_tcl_list ("$phpEscapedCo ntents"); }]
append php [subst {[format %c 125] }]
append php { ?>}
set cannotRunPHP [catch {exec "echo '$php' | php" >@stdout
2>&stderr} errorMsg]
if {$cannotRunPHP} {
puts $errorMsg
return {}
} else {
if {![IS_LIST $contentsList]} { set contentsList [split
$contentsList] }
if {[llength $contentsList] == 0} { lappend contentsList {?} }
return [lrange $contentsList [expr {[lsearch -exact $contentsList
"?"] + 1}] end]
}

}
[/TCL]

The command-line PHP should look like this:

[PHP]
<? if (@is_file("./functions.inc.p hp")) {
require_once("./functions.inc.p hp"); echo
xml_to_tcl_list ("$phpEscapedCo ntents"); } ?>
[/PHP]

Note that $phpEscapedCont ents is a TCL variable, not a PHP variable

Ok, so this is what should happen:

1) PHP function xml_to_tcl_list will convert the inputted escaped XML
string into a TCL list
2) I need to return that TCL list into $contentsList and return it so
the proc returns a TCL list

However, it never gets that far, here is the error I get:

couldn't execute "echo '<? if (@is_file("./functions.inc.p hp")) {
require_once("./functions.inc.p hp"); echo xml_to_tcl_list ("&lt;?xml
version=&quot;1 .0&quot; encod": file name too long
I am sure I am going at this the wrong way, but I can't understand the
right way (TCL DOM parsing is far FAR beyond my ability to understand,
I've read manuals, tutorials, books, to no avail: I simply don't
understand how TCL can ever parse XML, I only understand simple PHP
parsing XML)

So at this point, all I want to do is convert an XML string into a TCL
list, and the only way I know how to do it is via PHP, but I can't get
all three languages to cooperate.

Help appreciated.

Thanx
Phil

Nov 25 '06 #1
27 5101
comp.lang.tcl wrote:
set cannotRunPHP [catch {exec "echo '$php' | php" >@stdout
2>&stderr} errorMsg]
You need to re-read the man page on exec. The first argument to exec is
a filename that will be exec'd; it is not a command line. If you want to
run a command line you should exec a command line processor (/bin/sh,
command.com, whatever).

Since "php" is what you want to exec, and $php is what you want to send
to its stdin, use "<<" (documented on the exec man page):

if {[catch {exec php << $php} result]} {
puts "error exec'ing php: $resulut"
} else {
puts "php result: $result"
}

You can read a wiki page on the subject here: http://mini.net/tcl/exec
Nov 25 '06 #2

Bryan Oakley wrote:
comp.lang.tcl wrote:
set cannotRunPHP [catch {exec "echo '$php' | php" >@stdout
2>&stderr} errorMsg]

You need to re-read the man page on exec. The first argument to exec is
a filename that will be exec'd; it is not a command line. If you want to
run a command line you should exec a command line processor (/bin/sh,
command.com, whatever).

Since "php" is what you want to exec, and $php is what you want to send
to its stdin, use "<<" (documented on the exec man page):

if {[catch {exec php << $php} result]} {
puts "error exec'ing php: $resulut"
} else {
puts "php result: $result"
}

Now I get this error:

couldn't execute "php": no such file or directory

When I try this:

[TCL]
set cannotRunPHP [catch {exec exec php << $php >@stdout 2>&stderr}
errorMsg]
if {$cannotRunPHP} {
puts $errorMsg
return {}
} else {
if {![IS_LIST $contentsList]} { set contentsList [split
$contentsList] }
if {[llength $contentsList] == 0} { lappend contentsList {?} }
return [lrange $contentsList [expr {[lsearch -exact $contentsList
"?"] + 1}] end]
}

[/TCL]

Wow this should only take an hour, it's taken 3 days so far!

Phil
>
You can read a wiki page on the subject here: http://mini.net/tcl/exec
Nov 25 '06 #3
comp.lang.tcl schrieb:
My TCL proc, XML_GET_ALL_ELE MENT_ATTRS, is supposed to convert an XML
file into a TCL list as follows:

attr1 {val1} attr2 {val2} ... attrN {valN}

This is the TCL code that does this:

[TCL]
set contents [read $fileID [file size ${fileName}.xml]]; close $fileID
if {![string equal $switch -body]} {
# ONLY DO THIS IF THE XML CONTENTS CONTAIN NO BODY - WILL UPGRADE AT
A LATER DATE 11/24/2006 - PHIL
global serverName
if {![info exists serverName]} {
global env
source ./cgi_globals.tcl
global serverName
}

if {[string length [info procs {URL_ENCODE}]] == 0} { source
./url_procs.tcl }; # INCLUDE NEW url_procs.tcl URL TCL LIBRARY
if {[string length [info procs {IS_LIST}]] == 0} { source
{./tcl_string_tool s.tcl} }; # INCLUDE THE TCL STRING LIBRARY CONTAINING
PROC is_list IF !FOUND

# BLOCK TO CREATE THE PHP SCRIPT TO PIPE INTO php.exe
regsub -all {'} [XML_CLEANUP_ATT RIBUTE $contents] {\"}
phpEscapedConte nts
regsub -all {"} $phpEscapedCont ents {\&quot;} phpEscapedConte nts
set php {<? }
append php [subst { if (@is_file("./functions.inc.p hp")) [format %c
123] }]
append php { require_once("./functions.inc.p hp"); }
append php [subst { echo xml_to_tcl_list ("$phpEscapedCo ntents"); }]
append php [subst {[format %c 125] }]
append php { ?>}
set cannotRunPHP [catch {exec "echo '$php' | php" >@stdout
2>&stderr} errorMsg]
if {$cannotRunPHP} {
puts $errorMsg
return {}
} else {
if {![IS_LIST $contentsList]} { set contentsList [split
$contentsList] }
if {[llength $contentsList] == 0} { lappend contentsList {?} }
return [lrange $contentsList [expr {[lsearch -exact $contentsList
"?"] + 1}] end]
}

}
[/TCL]

The command-line PHP should look like this:

[PHP]
<? if (@is_file("./functions.inc.p hp")) {
require_once("./functions.inc.p hp"); echo
xml_to_tcl_list ("$phpEscapedCo ntents"); } ?>
[/PHP]

Note that $phpEscapedCont ents is a TCL variable, not a PHP variable

Ok, so this is what should happen:

1) PHP function xml_to_tcl_list will convert the inputted escaped XML
string into a TCL list
2) I need to return that TCL list into $contentsList and return it so
the proc returns a TCL list

However, it never gets that far, here is the error I get:

couldn't execute "echo '<? if (@is_file("./functions.inc.p hp")) {
require_once("./functions.inc.p hp"); echo xml_to_tcl_list ("&lt;?xml
version=&quot;1 .0&quot; encod": file name too long

I am sure I am going at this the wrong way, but I can't understand the
right way (TCL DOM parsing is far FAR beyond my ability to understand,
I've read manuals, tutorials, books, to no avail: I simply don't
understand how TCL can ever parse XML, I only understand simple PHP
parsing XML)

So at this point, all I want to do is convert an XML string into a TCL
list, and the only way I know how to do it is via PHP, but I can't get
all three languages to cooperate.
If you showed us part of the XML there surely is a shorter way with one
of the XML parsers for Tcl like tdom, but maybe your just confused by
the difference between DOM and SAX style xml parsing.

Michael
Nov 25 '06 #4

Michael Schlenker wrote:
comp.lang.tcl schrieb:
My TCL proc, XML_GET_ALL_ELE MENT_ATTRS, is supposed to convert an XML
file into a TCL list as follows:

attr1 {val1} attr2 {val2} ... attrN {valN}

This is the TCL code that does this:

[TCL]
set contents [read $fileID [file size ${fileName}.xml]]; close $fileID
if {![string equal $switch -body]} {
# ONLY DO THIS IF THE XML CONTENTS CONTAIN NO BODY - WILL UPGRADE AT
A LATER DATE 11/24/2006 - PHIL
global serverName
if {![info exists serverName]} {
global env
source ./cgi_globals.tcl
global serverName
}

if {[string length [info procs {URL_ENCODE}]] == 0} { source
./url_procs.tcl }; # INCLUDE NEW url_procs.tcl URL TCL LIBRARY
if {[string length [info procs {IS_LIST}]] == 0} { source
{./tcl_string_tool s.tcl} }; # INCLUDE THE TCL STRING LIBRARY CONTAINING
PROC is_list IF !FOUND

# BLOCK TO CREATE THE PHP SCRIPT TO PIPE INTO php.exe
regsub -all {'} [XML_CLEANUP_ATT RIBUTE $contents] {\"}
phpEscapedConte nts
regsub -all {"} $phpEscapedCont ents {\&quot;} phpEscapedConte nts
set php {<? }
append php [subst { if (@is_file("./functions.inc.p hp")) [format %c
123] }]
append php { require_once("./functions.inc.p hp"); }
append php [subst { echo xml_to_tcl_list ("$phpEscapedCo ntents"); }]
append php [subst {[format %c 125] }]
append php { ?>}
set cannotRunPHP [catch {exec "echo '$php' | php" >@stdout
2>&stderr} errorMsg]
if {$cannotRunPHP} {
puts $errorMsg
return {}
} else {
if {![IS_LIST $contentsList]} { set contentsList [split
$contentsList] }
if {[llength $contentsList] == 0} { lappend contentsList {?} }
return [lrange $contentsList [expr {[lsearch -exact $contentsList
"?"] + 1}] end]
}

}
[/TCL]

The command-line PHP should look like this:

[PHP]
<? if (@is_file("./functions.inc.p hp")) {
require_once("./functions.inc.p hp"); echo
xml_to_tcl_list ("$phpEscapedCo ntents"); } ?>
[/PHP]

Note that $phpEscapedCont ents is a TCL variable, not a PHP variable

Ok, so this is what should happen:

1) PHP function xml_to_tcl_list will convert the inputted escaped XML
string into a TCL list
2) I need to return that TCL list into $contentsList and return it so
the proc returns a TCL list

However, it never gets that far, here is the error I get:

couldn't execute "echo '<? if (@is_file("./functions.inc.p hp")) {
require_once("./functions.inc.p hp"); echo xml_to_tcl_list ("&lt;?xml
version=&quot;1 .0&quot; encod": file name too long
I am sure I am going at this the wrong way, but I can't understand the
right way (TCL DOM parsing is far FAR beyond my ability to understand,
I've read manuals, tutorials, books, to no avail: I simply don't
understand how TCL can ever parse XML, I only understand simple PHP
parsing XML)

So at this point, all I want to do is convert an XML string into a TCL
list, and the only way I know how to do it is via PHP, but I can't get
all three languages to cooperate.
If you showed us part of the XML there surely is a shorter way with one
of the XML parsers for Tcl like tdom, but maybe your just confused by
the difference between DOM and SAX style xml parsing.
There is, but I've said this to nearly ever TCL and PHP developer on
earth: I do not understand XML parsing at all, DOM, SAX, xQuery,
X[whatever else], none of it makes sense to me and I cannot understand
the books, tutorials and online guides (not to mention the tips from
far smarter people than I) that has barraged me; all of it makes
absolutely no sense to me.

At this point the only way I can parse XML is using PHP, because that's
literally the ONLY way I can do it, period!

But if you want to see a sample of the XML I'm working with, here it
is:

<?xml version="1.0" encoding="utf-8" ?><trivia><entr y id="1101"
triviaID="233" question="Who wrote &quot;Trilog y of Knowledge&quot; ?"
answerID="1" correctAnswerID ="1" answer="Believe r"
expDate="113963 4000"></entry><entry id="1102" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="2"
correctAnswerID ="1" answer="Saviour Machine"
expDate="113963 4000"></entry><entry id="1103" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="3"
correctAnswerID ="1" answer="Seventh Avenue"
expDate="113963 4000"></entry><entry id="1104" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="4"
correctAnswerID ="1" answer="Inevita ble End"
expDate="113963 4000"></entry><entry id="1105" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="5"
correctAnswerID ="1" answer="No such song existed"
expDate="113963 4000"></entry>

Phil

>
Michael
Nov 25 '06 #5
comp.lang.tcl wrote:
Bryan Oakley wrote:
>>comp.lang.t cl wrote:
>> set cannotRunPHP [catch {exec "echo '$php' | php" >@stdout
2>&stderr} errorMsg]

You need to re-read the man page on exec. The first argument to exec is
a filename that will be exec'd; it is not a command line. If you want to
run a command line you should exec a command line processor (/bin/sh,
command.com , whatever).

Since "php" is what you want to exec, and $php is what you want to send
to its stdin, use "<<" (documented on the exec man page):

if {[catch {exec php << $php} result]} {
puts "error exec'ing php: $resulut"
} else {
puts "php result: $result"
}

Now I get this error:

couldn't execute "php": no such file or directory

When I try this:

[TCL]
set cannotRunPHP [catch {exec exec php << $php >@stdout 2>&stderr}
errorMsg]
if {$cannotRunPHP} {
puts $errorMsg
return {}
} else {
if {![IS_LIST $contentsList]} { set contentsList [split
$contentsList] }
if {[llength $contentsList] == 0} { lappend contentsList {?} }
return [lrange $contentsList [expr {[lsearch -exact $contentsList
"?"] + 1}] end]
}

[/TCL]

Wow this should only take an hour, it's taken 3 days so far!
When you are learning a new language, it always takes much longer to
solve problems. And in your case I'm afraid, you aren't taking much time
to actually learn the language which is compounding the problem.

The answer to your current problem is well documented in the exec man
page, and on the exec pages on the tcler's wiki. The problem you are
encountering is very simple: you are telling it to execute "php" but tcl
can't find "php". The short answer is, you either have to explicitly
tell the exec command which *file* to execute (eg: exec
/usr/local/bin/php), or you have to make sure that the file you tell it
exists somewhere within a directory defined in your PATH environment
variable.

Phil, I'm sorry you're having so many problems. You are correct that
this probably should have taken only an hour or two for a seasoned
programmer, but you are not a seasoned programmer and properly parsing
XML is, generally speaking, a Hard Problem. At least, it's hard when you
choose to not use proper XML parsing solutions and instead rely on a
series of text transformations .

Tcl is a very powerful language, but it doesn't have built-in facilities
to parse XML. This is not a weakness of Tcl, it's just the way it is.
The beauty of Tcl is, people can write extensions to the language to do
just about anything, including parsing XML. Unfortunately, you are
choosing not to take the time to learn how to use them.

I'll again recommend trying the xml2list function documented here:
http://mini.net/tcl/3919. I'm guessing that will work good enough for
you. Fortunately, it appears you're working on a simply hobby
application rather than a commercial application so we don't have to
worry so much about robustness.

Nov 25 '06 #6

Bryan Oakley wrote:
comp.lang.tcl wrote:
Bryan Oakley wrote:
>comp.lang.tc l wrote:

set cannotRunPHP [catch {exec "echo '$php' | php" >@stdout
2>&stderr} errorMsg]

You need to re-read the man page on exec. The first argument to exec is
a filename that will be exec'd; it is not a command line. If you want to
run a command line you should exec a command line processor (/bin/sh,
command.com, whatever).

Since "php" is what you want to exec, and $php is what you want to send
to its stdin, use "<<" (documented on the exec man page):

if {[catch {exec php << $php} result]} {
puts "error exec'ing php: $resulut"
} else {
puts "php result: $result"
}


Now I get this error:

couldn't execute "php": no such file or directory

When I try this:

[TCL]
set cannotRunPHP [catch {exec exec php << $php >@stdout 2>&stderr}
errorMsg]
if {$cannotRunPHP} {
puts $errorMsg
return {}
} else {
if {![IS_LIST $contentsList]} { set contentsList [split
$contentsList] }
if {[llength $contentsList] == 0} { lappend contentsList {?} }
return [lrange $contentsList [expr {[lsearch -exact $contentsList
"?"] + 1}] end]
}

[/TCL]

Wow this should only take an hour, it's taken 3 days so far!

When you are learning a new language, it always takes much longer to
solve problems. And in your case I'm afraid, you aren't taking much time
to actually learn the language which is compounding the problem.

The answer to your current problem is well documented in the exec man
page, and on the exec pages on the tcler's wiki. The problem you are
encountering is very simple: you are telling it to execute "php" but tcl
can't find "php". The short answer is, you either have to explicitly
tell the exec command which *file* to execute (eg: exec
/usr/local/bin/php), or you have to make sure that the file you tell it
exists somewhere within a directory defined in your PATH environment
variable.

Phil, I'm sorry you're having so many problems. You are correct that
this probably should have taken only an hour or two for a seasoned
programmer, but you are not a seasoned programmer and properly parsing
XML is, generally speaking, a Hard Problem. At least, it's hard when you
choose to not use proper XML parsing solutions and instead rely on a
series of text transformations .
Bryan, you're going to die when you hear this: I have 9+ years web
development experience, been doing TCL for about 7 years (mostly via
Vignette), have 5 certifications including a master PHP certification..
and I have no clue how to do any of this. Thus I am a seasoned
programmer (though honestly nobody here will ever recognize or believe
that)

Tcl is a very powerful language, but it doesn't have built-in facilities
to parse XML. This is not a weakness of Tcl, it's just the way it is.
The beauty of Tcl is, people can write extensions to the language to do
just about anything, including parsing XML. Unfortunately, you are
choosing not to take the time to learn how to use them.
I've said this over and over again: it's not that I won't take the
time, it's that I CANNOT do it because I have a learning disability
called Attention Deficit Disorder which psychologically does not permit
me to take the time to learn it. I am unable to understand man pages
like you and Cameron and other can do in your sleep. I read the Tcl
extensions online but don't understand them. The pages are in
Hungarian to me. I can't fathom them, I don't know how to install
them, manipulate them, use them, anything. If people could show me a
very very simple way of parsing this:

<?xml version="1.0" encoding="utf-8" ?><trivia><entr y id="1101"
triviaID="233" question="Who wrote &quot;Trilog y of Knowledge&quot; ?"
answerID="1" correctAnswerID ="1" answer="Believe r"
expDate="113963 4000"></entry><entry id="1102" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="2"
correctAnswerID ="1" answer="Saviour Machine"
expDate="113963 4000"></entry><entry id="1103" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="3"
correctAnswerID ="1" answer="Seventh Avenue"
expDate="113963 4000"></entry><entry id="1104" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="4"
correctAnswerID ="1" answer="Inevita ble End"
expDate="113963 4000"></entry><entry id="1105" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="5"
correctAnswerID ="1" answer="No such song existed"
expDate="113963 4000"></entry></trivia>

Into this:

id 1101 triviaID 233 question {Who wrote &quot;Trilog y of
Knowledge&quot; ?} answerID 1 correctAnswerID 1 answer Believer expDate
113963500

[etc]

Then that would do it, but I guess the problem is that I can't explain
my problem, nor my disabilities, well enough for the programming
community to fathom my dilemma.

Phil
>
I'll again recommend trying the xml2list function documented here:
http://mini.net/tcl/3919. I'm guessing that will work good enough for
you. Fortunately, it appears you're working on a simply hobby
application rather than a commercial application so we don't have to
worry so much about robustness.
Nov 25 '06 #7
comp.lang.tcl wrote:
... I do not understand XML parsing at all, DOM, SAX, xQuery,
X[whatever else], none of it makes sense to me and I cannot understand
the books, tutorials and online guides (not to mention the tips from
far smarter people than I) that has barraged me; all of it makes
absolutely no sense to me.

At this point the only way I can parse XML is using PHP, because that's
literally the ONLY way I can do it, period!

But if you want to see a sample of the XML I'm working with, here it
is:

<?xml version="1.0" encoding="utf-8" ?><trivia><entr y id="1101"
triviaID="233" question="Who wrote &quot;Trilog y of Knowledge&quot; ?"
answerID="1" correctAnswerID ="1" answer="Believe r"
expDate="113963 4000"></entry><entry id="1102" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="2"
correctAnswerID ="1" answer="Saviour Machine"
expDate="113963 4000"></entry><entry id="1103" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="3"
correctAnswerID ="1" answer="Seventh Avenue"
expDate="113963 4000"></entry><entry id="1104" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="4"
correctAnswerID ="1" answer="Inevita ble End"
expDate="113963 4000"></entry><entry id="1105" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="5"
correctAnswerID ="1" answer="No such song existed"
expDate="113963 4000"></entry>
That data is mal-formed XML. For example, you are missing the closing
</triviatag.

Here's a solution that works with the above data. I've mentioned the
"xml2list" proc a couple of times, but with the sample data I see your
data will need a little extra pre-processing.

Step 1: copy the proc "xml2list" from this page: http://mini.net/tcl/3919

Second, enter the following, which is taking the above data verbatim and
storing it in a variable:

set data {<?xml version="1.0" encoding="utf-8" ?><trivia><entr y
id="1101"
triviaID="233" question="Who wrote &quot;Trilog y of Knowledge&quot; ?"
answerID="1" correctAnswerID ="1" answer="Believe r"
expDate="113963 4000"></entry><entry id="1102" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="2"
correctAnswerID ="1" answer="Saviour Machine"
expDate="113963 4000"></entry><entry id="1103" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="3"
correctAnswerID ="1" answer="Seventh Avenue"
expDate="113963 4000"></entry><entry id="1104" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="4"
correctAnswerID ="1" answer="Inevita ble End"
expDate="113963 4000"></entry><entry id="1105" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="5"
correctAnswerID ="1" answer="No such song existed"
expDate="113963 4000"></entry>}

Your data is missing an ending </triviatag, so we have to add it for
this specific example. I don't know if this is a problem you'll have to
solve with your full dataset. Also, the xml2list proc doesn't like the
leading <?xml...stuff . So, let's modify your data:

# remove the leading <?xml...?data
regexp {<\?.*?\?>(.*$) } $data -- data

# add a trailing </triviawhich is missing from
# the sample data
set data "$data</trivia>"

And now, convert it to a list and print it out:

set result [xml2list $data]
puts $result

If you didn't introduce any typos, you'll get the following output:

trivia {} {{entry {id 1101 triviaID 233 question {Who wrote
&quot;Trilog y of Knowledge&quot; ?} answerID 1 correctAnswerID 1 answer
Believer expDate 1139634000} {}} {entry {id 1102 triviaID 233 question
{Who wrote &quot;Trilog y of Knowledge&quot; ?} answerID 2 correctAnswerID
1 answer {Saviour Machine} expDate 1139634000} {}} {entry {id 1103
triviaID 233 question {Who wrote &quot;Trilog y of Knowledge&quot; ?}
answerID 3 correctAnswerID 1 answer {Seventh Avenue} expDate 1139634000}
{}} {entry {id 1104 triviaID 233 question {Who wrote &quot;Trilog y of
Knowledge&quot; ?} answerID 4 correctAnswerID 1 answer {Inevitable End}
expDate 1139634000} {}} {entry {id 1105 triviaID 233 question {Who wrote
&quot;Trilog y of Knowledge&quot; ?} answerID 5 correctAnswerID 1 answer
{No such song existed} expDate 1139634000} {}}}

The above is a valid tcl list that you can now process with normal tcl
list-handling commands. Do *not* process this list with string
transformations (such as converting &quot; to a quote). If you do, you
run the risk of breaking it's list-ness. Instead, loop over the data and
do the conversion as a final step on a element-by-element basis.

Does this help? It's not robust; the xml2list assumes you have proper
xml with a balanced set of tags (or in the specific case in this
message, with a missing </triviatag). Hopefully, though, it will at
least get you started.
Nov 25 '06 #8

Bryan Oakley wrote:
comp.lang.tcl wrote:
... I do not understand XML parsing at all, DOM, SAX, xQuery,
X[whatever else], none of it makes sense to me and I cannot understand
the books, tutorials and online guides (not to mention the tips from
far smarter people than I) that has barraged me; all of it makes
absolutely no sense to me.

At this point the only way I can parse XML is using PHP, because that's
literally the ONLY way I can do it, period!

But if you want to see a sample of the XML I'm working with, here it
is:

<?xml version="1.0" encoding="utf-8" ?><trivia><entr y id="1101"
triviaID="233" question="Who wrote &quot;Trilog y of Knowledge&quot; ?"
answerID="1" correctAnswerID ="1" answer="Believe r"
expDate="113963 4000"></entry><entry id="1102" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="2"
correctAnswerID ="1" answer="Saviour Machine"
expDate="113963 4000"></entry><entry id="1103" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="3"
correctAnswerID ="1" answer="Seventh Avenue"
expDate="113963 4000"></entry><entry id="1104" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="4"
correctAnswerID ="1" answer="Inevita ble End"
expDate="113963 4000"></entry><entry id="1105" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="5"
correctAnswerID ="1" answer="No such song existed"
expDate="113963 4000"></entry>

That data is mal-formed XML. For example, you are missing the closing
</triviatag.

Here's a solution that works with the above data. I've mentioned the
"xml2list" proc a couple of times, but with the sample data I see your
data will need a little extra pre-processing.

Step 1: copy the proc "xml2list" from this page: http://mini.net/tcl/3919
Ok done
>
Second, enter the following, which is taking the above data verbatim and
storing it in a variable:

set data {<?xml version="1.0" encoding="utf-8" ?><trivia><entr y
id="1101"
triviaID="233" question="Who wrote &quot;Trilog y of Knowledge&quot; ?"
answerID="1" correctAnswerID ="1" answer="Believe r"
expDate="113963 4000"></entry><entry id="1102" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="2"
correctAnswerID ="1" answer="Saviour Machine"
expDate="113963 4000"></entry><entry id="1103" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="3"
correctAnswerID ="1" answer="Seventh Avenue"
expDate="113963 4000"></entry><entry id="1104" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="4"
correctAnswerID ="1" answer="Inevita ble End"
expDate="113963 4000"></entry><entry id="1105" triviaID="233"
question="Who wrote &quot;Trilog y of Knowledge&quot; ?" answerID="5"
correctAnswerID ="1" answer="No such song existed"
expDate="113963 4000"></entry>}

Your data is missing an ending </triviatag, so we have to add it for
this specific example. I don't know if this is a problem you'll have to
solve with your full dataset. Also, the xml2list proc doesn't like the
leading <?xml...stuff . So, let's modify your data:

Sorry that was my fault, I left off the </triviatag when I copied and
pasted onto here. The closing tags do exist in all of my XML files
>
# remove the leading <?xml...?data
regexp {<\?.*?\?>(.*$) } $data -- data

# add a trailing </triviawhich is missing from
# the sample data
set data "$data</trivia>"

And now, convert it to a list and print it out:

set result [xml2list $data]
puts $result

If you didn't introduce any typos, you'll get the following output:

No I don't, I get the following error, spawned from within xml2list:

unmatched open quote in list while executing "lindex $item 0"
("default" arm line 2) invoked from within "switch -regexp -- $item {
^# {append res "{[lrange $item 0 end]} " ; #text item} ^/ { regexp
{/(.+)} $item -..." (procedure "xml2list" line 9)

This is what I did:

[TCL]
# USE xml2list PROC WITHIN THIS LIBRARY AS YOUR DEFAULT MEANS OF
PARSING XML INTO TCL LIST
if {![string equal $switch -body] && [string length [info procs
{xml2list}]] 0} {
regexp {<\?.*?\?>(.*$) } $contents -- contents
return [xml2list $contents]
}
[/TCL]
>
trivia {} {{entry {id 1101 triviaID 233 question {Who wrote
&quot;Trilog y of Knowledge&quot; ?} answerID 1 correctAnswerID 1 answer
Believer expDate 1139634000} {}} {entry {id 1102 triviaID 233 question
{Who wrote &quot;Trilog y of Knowledge&quot; ?} answerID 2 correctAnswerID
1 answer {Saviour Machine} expDate 1139634000} {}} {entry {id 1103
triviaID 233 question {Who wrote &quot;Trilog y of Knowledge&quot; ?}
answerID 3 correctAnswerID 1 answer {Seventh Avenue} expDate 1139634000}
{}} {entry {id 1104 triviaID 233 question {Who wrote &quot;Trilog y of
Knowledge&quot; ?} answerID 4 correctAnswerID 1 answer {Inevitable End}
expDate 1139634000} {}} {entry {id 1105 triviaID 233 question {Who wrote
&quot;Trilog y of Knowledge&quot; ?} answerID 5 correctAnswerID 1 answer
{No such song existed} expDate 1139634000} {}}}

The above is a valid tcl list that you can now process with normal tcl
list-handling commands. Do *not* process this list with string
transformations (such as converting &quot; to a quote). If you do, you
run the risk of breaking it's list-ness. Instead, loop over the data and
do the conversion as a final step on a element-by-element basis.

Does this help? It's not robust; the xml2list assumes you have proper
xml with a balanced set of tags (or in the specific case in this
message, with a missing </triviatag). Hopefully, though, it will at
least get you started.
Like I said, I do have balanced XML (just didn't produce it here tis
all), but xml2list produces errors when I try to read it

Phil

Nov 25 '06 #9
comp.lang.tcl wrote:
id 1101 triviaID 233 question {Who wrote &quot;Trilog y of
Knowledge&quot; ?} answerID 1 correctAnswerID 1 answer Believer expDate
113963500
Take the zip file I posted. Install it. Call

set x [::xsxp::parse $myXml]
return [lindex [lindex $x 2] 1]

(I think that's the right path thru the list to the attributes of the
first child element. Otherwise, print out the list and see which
elements you have to grab.)

--
Darren New / San Diego, CA, USA (PST)
Scruffitarianis m - Where T-shirt, jeans,
and a three-day beard are "Sunday Best."
Nov 25 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
2044
by: Ling Lee | last post by:
Hello. I'm trying to write a small program that lets you put in a number as an integer and then it tells you the textuel representation of the number. Like if your input is 42, it will say four two. I found out that I have to make a dictionary like this: List = { 1:"one", 2:"two" and so on )
12
2177
by: teoryn | last post by:
I've been spending today learning python and as an exercise I've ported a program I wrote in java that unscrambles a word. Before describing the problem, here's the code: *--beginning of file--* #!/usr/bin/python # Filename: unscram.py def sort_string(word): '''Returns word in lowercase sorted alphabetically'''
5
4210
by: Vigneshwar Pilli via DotNetMonster.com | last post by:
string connectionString1 = "server=(local); user=sa;password=sa; database=sonic"; System.Data.SqlClient.SqlConnection dbConnection1 = new System.Data.SqlClient.SqlConnection(connectionString1); System.Data.SqlClient.SqlCommand dbCommand1 = new System.Data.SqlClient.SqlCommand();
2
4432
by: ajikoe | last post by:
Hi, I tried to follow the example in swig homepage. I found error which I don't understand. I use bcc32, I already include directory where my python.h exist in bcc32.cfg. /* File : example.c */ #include <time.h>
2
4534
by: Mike Collins | last post by:
I cannot get the correct drop down list value from a drop down I have on my web form. I get the initial value that was loaded in the list. It was asked by someone else what the autopostback was set to...it is set to false. Can someone show me what I am doing wrong and tell me the correct way? Thank you. In the page load event, I am...
3
2072
by: Varangian | last post by:
Hello, there I have a problem with regards to System.Collections.Generic.List<T> I need to pass a class with implements an interface - TestClass : IPerson I put this class in a List<TestClass> = new List<TestClass>(); then I pass this List<TestClass> to a function which takes an argument List<IPerson> person
5
3772
by: Learner | last post by:
Hello, Here is the code snippet I got strucked at. I am unable to convert the below line of code to its equavalent vb.net code. could some one please help me with this? static public List<RoleData> GetRoles() { return GetRoles(null, false); }
3
1535
by: =?Utf-8?B?dmluY2VudHc1Ng==?= | last post by:
I have an ASP.NET 2.0 application. It is pretty basic. What it does is shows a gridview of data from a stored procedure. The user can also select a date filter. The problem is that sometimes an error is thrown about getting the data. If I go in and make a change to the .cs file, the application runs fine. The change I make is like insert...
6
3513
by: efrenba | last post by:
Hi, I came from delphi world and now I'm doing my first steps in C++. I'm using C++builder because its ide is like delphi although I'm trying to avoid the vcl. I need to insert new features to an old program that I wrote in delphi and it's a good opportunity to start with c++.
0
7541
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7464
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7979
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7497
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7826
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6065
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
5107
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
1
1960
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1074
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.