#!/bin/sh
# Copyright for the Uniform Repository Service (c) 1995 - 2012,
# by Gerald Banon. All rights reserved.
# Version 2.1
# parseXML.tcl \
namespace eval parseXML {
# >
# ----------------------------------------------------------------------
# Lindex
proc Lindex {list iList} {
foreach i $iList {
set list [lindex $list $i]
}
return $list
}
# Lindex - end
# ----------------------------------------------------------------------
# Llength
proc Llength {list iList} {
return [llength [Lindex $list $iList]]
}
# Llength - end
# ----------------------------------------------------------------------
# Lchange
# example:
# Lchange {a {} c} 1 {b d}
# => a {b d} c
proc Lchange {list iList arg} {
set list2 $arg
while {![string equal {} $iList]} {
set i [lindex $iList end]
set iList [lreplace $iList end end]
set list2 [lreplace [Lindex $list $iList] $i $i $list2]
}
return $list2
}
# Lchange - end
# ----------------------------------------------------------------------
# Lappend
# example:
# Lappend {a b c} {} d
# => a b c d
# Lappend {a b c} 1 d
# => a {b d} c
# Lappend {a {} c} 1 {b d}
# => a {{b d}} c
# Lappend {a {b x} c} {1 0} d
# => a {{b d} x} c
proc Lappend {list iList arg} {
# global xxx
set list2 [Lindex $list $iList]
lappend list2 $arg
while {![string equal {} $iList]} {
# puts $iList
set i [lindex $iList end]
set iList [lreplace $iList end end]
# puts --[Lindex $list $iList]--
# puts $i
# incr xxx
# puts -$xxx-
# if [string equal 2 $xxx] {error {stop}}
# puts 1.$list2
set list2 [lreplace [Lindex $list $iList] $i $i $list2]
# puts 2.$list2
}
return $list2
}
# Lappend - end
# ----------------------------------------------------------------------
# CodeAttributeValue
proc CodeAttributeValue {inputString} {
set attributeCharacter 0
set outputString {}
set tagFlag 0
foreach character [split $inputString {}] {
# since " are allowed within tag value, tag value strings must identified
if [string equal {<} $character] {
set tagFlag 1
} elseif {[string equal {>} $character] && !$attributeCharacter} {
# since > are allowed within attribute value, && !$attributeCharacter must be added in the if condition
set tagFlag 0
}
if $tagFlag {
# inside tag name - outside tag value
if $attributeCharacter {
if [string equal {"} $character] {set attributeCharacter 0}
} else {
if [string equal {"} $character] {set attributeCharacter 1}
}
if $attributeCharacter {
if [string equal {<} $character] {
lappend outputString {!<!}
} elseif [string equal {>} $character] {
lappend outputString {!>!}
} else {
lappend outputString $character
}
} else {
lappend outputString $character
}
} else {
lappend outputString $character
}
}
return [join $outputString {}]
}
# CodeAttributeValue - end
# ----------------------------------------------------------------------
# DecodeAttributeValue
proc DecodeAttributeValue {inputString} {
regsub -all {!>!} $inputString {>} outputString ;# !>! --> >
regsub -all {!<!} $outputString {<} outputString ;# !<! --> <
return $outputString
}
# DecodeAttributeValue - end
# ----------------------------------------------------------------------
# ProcessTag
proc ProcessTag {parentName iList tag createSchema} {
global parseXML::dataList
global parseXML::tagNameList
# global createSchema
set tagName $tag
set attributePart {}
set attributeList {}
regexp {([^ ]*) (.*)} $tag m tagName attributePart
regsub -all {([^=]*)=("[^"]*")} $attributePart {\1 \2} attributeList ;# drop =
if [string equal {} $parentName] {
set dataList [list [list $tagName $attributeList {}]]
} else {
# puts [list $dataList $iList [list $parentName.$tagName $attributeList {}]]
set dataList [Lappend $dataList $iList [list $parentName.$tagName $attributeList {}]]
}
# Create tagNameList
if $createSchema {
if [string equal {} $parentName] {
set tagName2 $tagName
} else {
set tagName2 $parentName.$tagName
}
set i 1 ;# must be 1 to simplify ExtractData
# if [regexp {PELLEGRINO} $attributeList] {puts $attributeList}
foreach {attributeName attributeValue} $attributeList {
# if {[lsearch $tagNameList [list $tagName2,$attributeName *]] == -1} {
lappend tagNameList [list $tagName2,$attributeName [concat $iList [expr [Llength $dataList $iList] - 1] 1 $i]]
# }
incr i 2 ;# must be 2 to simplify ExtractData
}
}
# Create tagNameList - end
return $tagName
}
# ProcessTag - end
# ----------------------------------------------------------------------
# XML2tcl
proc XML2tcl {xml createSchema} {
global parseXML::dataList ;# set by XML2tcl2
global parseXML::tagNameList ;# set by XML2tcl2 if createSchema == 1
global parseXML::schema ;# set by XML2tcl
# set xxx [CodeAttributeValue $xml]
# Store xxx {../../../../../iconet.com.br/banon/2005/08.13.18.19/doc/xxx.txt}
XML2tcl2 {} {} [CodeAttributeValue $xml] $createSchema
set dataList [DecodeAttributeValue $dataList]
if $createSchema {CreateTagArrays} ;# needed by Select
if $createSchema {set schema [join $tagNameList \n]}
}
# XML2tcl - end
# ----------------------------------------------------------------------
# XML2tcl2
proc XML2tcl2 {parentName iList xml createSchema} {
global parseXML::dataList ;# set by XML2tcl2
global parseXML::tagNameList ;# set by XML2tcl2 if createSchema == 1
# global createSchema
# if ![info exists createSchema] {set createSchema 0}
if {$createSchema && [string equal {} $parentName]} {set tagNameList {}}
# if [expr [info level] == 5] {return}
if [expr [info level] > 99] {return}
# puts [list level: [info level]]
set xml [string trim $xml "\n "]
regsub {<\?[^?]*\?>} $xml {} rest
set iList2 [concat $iList {0 2}]
# set i 1
# while {$i < 99 && ![string equal {} $rest]} # ;# doesn't when they are more than 98 items at the same level - commented by GJFB in 2010-12-19
while {![string equal {} $rest]} {
## puts [list i: $i]
# puts --$rest
if [regexp {<([^>]*)>(.*)} $rest m tag rest2] {
# puts >>$tag
if [regsub {/$} $tag {} tag] {
# puts OK1
# puts {}
# puts [list $parentName $iList $tag $createSchema]
ProcessTag $parentName $iList $tag $createSchema
set rest $rest2
} else {
# puts OK2
set tagName [ProcessTag $parentName $iList $tag $createSchema]
# puts [list tagName: $tagName]
# set length [string length $rest2]
# puts [string range $rest2 [expr $length - 30] end]
if [regexp -indices "$tagName>\[^<\]*(.*)" $rest2 m rest] {
# puts OK3
# regsub "$m$" $rest2 {} tagValue ;# doesn't work - tcl aborts
set tagValue [string range $rest2 0 [expr [lindex $m 0] - 1]]
set rest [string range $rest2 [lindex $rest 0] [lindex $rest 1]]
if [string equal {} $parentName] {
XML2tcl2 $tagName $iList2 $tagValue $createSchema
} else {
XML2tcl2 $parentName.$tagName $iList2 $tagValue $createSchema
}
} else {
# puts OK4
set rest $rest2 ;# case of
tag ( doesn't exist) - discard
}
}
set rest [string trim $rest "\n "]
} else {
set dataList [Lchange $dataList $iList $rest]
set rest {}
# Create tagNameList
if $createSchema {
# if {[lsearch $tagNameList [list $parentName *]] == -1} #
lappend tagNameList [list $parentName $iList]
# #
}
# Create tagNameList - end
}
set length [llength $iList2]
set index [expr $length - 2]
set position [lindex $iList2 $index]
incr position
# puts 1.$iList2
set iList2 [lreplace $iList2 $index $index $position]
# puts 2.$iList2
# incr i
}
}
# XML2tcl2 - end
# ----------------------------------------------------------------------
# CreateTagArrays
proc CreateTagArrays {} {
global parseXML::tagNameList ;# set in XML2tcl2
global parseXML::tagKeyArray
if [info exists tagKeyArray] {unset tagKeyArray}
foreach item $tagNameList {
set tagName [lindex $item 0]
set tagKey [lindex $item 1]
set tagKeyArray($tagKey) $tagName
}
}
# CreateTagArrays - end
# ----------------------------------------------------------------------
# ExtractData
# example:
# table.tr.td.a,href {0 2 0 2 0 2 0 1 1}
# table.tr.td.a {0 2 0 2 0 2 0 2}
# ExtractData {{0 2 0 2 0 2 0 2}}
# => yyy
proc ExtractData {indexList} {
global parseXML::dataList
if [string equal {} $indexList] {
set value {}
} else {
foreach index $indexList {
set value [lindex $dataList $index]
}
}
return [string trim $value]
}
# ExtractData - end
# ----------------------------------------------------------------------
# CreateTag
proc CreateTag {dataList} {
global parseXML::xml
# if [expr [info level] == 9] {return}
foreach tag $dataList {
set tagName [lindex $tag 0]
regsub {^.*\.} $tagName {} tagName
append xml "<$tagName"
set attributeList [lindex $tag 1]
foreach {attributeName attributeValue} $attributeList {
append xml " $attributeName=\"$attributeValue\""
}
set tagValue [lindex $tag 2]
if [string equal {} $tagValue] {
append xml " />"
} else {
append xml ">"
foreach item $tagValue {
if {[llength $item] == 1} {
append xml "$item "
} else {
CreateTag [list $item]
}
}
set xml [string trimright $xml]
append xml "$tagName>"
}
}
}
# CreateTag - end
# ----------------------------------------------------------------------
# TCL2xml
proc TCL2xml {listName} {
global parseXML::xml
upvar $listName dataList
if [info exists xml] {unset xml}
set xml {}
CreateTag $dataList
}
# TCL2xml - end
# ----------------------------------------------------------------------
# Select
# Examples:
# Select {} CURRICULO-VITAE.PRODUCAO-BIBLIOGRAFICA.ARTIGOS-PUBLICADOS.ARTIGO-PUBLICADO
# Select {0 2 1 2 1 2 0} ,SEQUENCIA-PRODUCAO
# Select {0 2 1 2 1 2 0} .DADOS-BASICOS-DO-ARTIGO,TITULO-DO-ARTIGO
# Select {0 2 1 2 1 2 0} .AUTORES
proc Select {key tag} {
# key == {}
# key == {0 2 1 2 1 2 0}
# tag == CURRICULO-VITAE.PRODUCAO-BIBLIOGRAFICA.ARTIGOS-PUBLICADOS.ARTIGO-PUBLICADO
# tag == AUTORES
global parseXML::tagNameList
global parseXML::tagKeyArray
# puts [llength $tagNameList]
# absoluteTagPath
set keyLength [llength $key]
if {$keyLength > 2} {
set tagList {}
# numberOfTags
# 4
set numberOfTags [expr ($keyLength + 1) / 2]
set i 1
# puts >>$key
# puts [split $tagKeyArray([lindex [array names tagKeyArray "$key *"] 0]) {.,}]
foreach item [split $tagKeyArray([lindex [array names tagKeyArray "$key *"] 0]) {.,}] {
lappend tagList $item
if {$i == $numberOfTags} {break}
incr i
}
set absoluteTagPath "[join $tagList {.}]$tag"
} else {
set absoluteTagPath $tag
}
# puts $absoluteTagPath
set keyList {}
if [string equal {} $key] {
foreach index [lsearch -all $tagNameList "$absoluteTagPath*"] {
lappend keyList [lindex [lindex $tagNameList $index] 1]
}
} else {
# puts "$absoluteTagPath* {$key *}"
# puts --[lsearch -all $tagNameList "$absoluteTagPath* {$key *}"]--
foreach index [lsearch -all $tagNameList "$absoluteTagPath* {$key *}"] {
lappend keyList [lindex [lindex $tagNameList $index] 1]
}
}
# puts $keyList
set absoluteTagPathList [split $absoluteTagPath {.,}]
set n [expr 2 * ([llength $absoluteTagPathList] - 1)]
set keyList2 {}
foreach item $keyList {
lappend keyList2 [lrange $item 0 $n]
}
return [lsort -unique $keyList2]
}
# Select - end
# ----------------------------------------------------------------------
# <
} ;# end namespace eval parseXML
# Testing
if 0 {
source cgi/mirrorfind-.tcl ;# Load
source utilities1.tcl ;# Store
source parseXML.tcl
}
if 0 {
# testing
if 0 {
set example {
ccc
yyy
eee
fff zzz ddd |
Banon, Gerald Jean Francis; Braga-Neto, Ulisses ID: dpi.inpe.br/banon-pc2@80/2006/11.01.13.53 | |