tclparser-8.1.tcl
来自「Linux下的MSN聊天程序源码」· TCL 代码 · 共 613 行 · 第 1/2 页
TCL
613 行
# name='value'## Arguments:# opts parser options# attrs attribute string given in a tag## Results:# Returns a Tcl list representing the name-value pairs in the # attribute string## A ">" occurring in the attribute list causes problems when parsing# the XML. This manifests itself by an unterminated attribute value# and a ">" appearing the element text.# In this case return a three element list;# the message "unterminated attribute value", the attribute list it# did manage to parse and the remainder of the attribute list.proc xml::tclparser::ParseAttrs {opts attrs} { set result {} while {[string length [string trim $attrs]]} { if {[regexp [::sgml::cl $::xml::Wsp]*($::xml::Name)[::sgml::cl $::xml::Wsp]*=[::sgml::cl $::xml::Wsp]*("|')([::sgml::cl ^<]*?)\\2(.*) $attrs discard attrName delimiter value attrs]} { lappend result $attrName [NormalizeAttValue $opts $value] } elseif {[regexp [::sgml::cl $::xml::Wsp]*$::xml::Name[::sgml::cl $::xml::Wsp]*=[::sgml::cl $::xml::Wsp]*("|')[::sgml::cl ^<]*\$ $attrs]} { return -code error [list {unterminated attribute value} $result $attrs] } else { return -code error "invalid attribute list" } } return $result}# xml::tclparser::NormalizeAttValue --## Perform attribute value normalisation. This involves:# . character references are appended to the value# . entity references are recursively processed and replacement value appended# . whitespace characters cause a space to be appended# . other characters appended as-is## Arguments:# opts parser options# value unparsed attribute value## Results:# Normalised value returned.proc xml::tclparser::NormalizeAttValue {opts value} { # sgmlparser already has backslashes protected # Protect Tcl specials regsub -all {([][$])} $value {\\\1} value # Deal with white space regsub -all "\[$::xml::Wsp\]" $value { } value # Find entity refs regsub -all {&([^;]+);} $value {[NormalizeAttValue:DeRef $opts {\1}]} value return [subst $value]}# xml::tclparser::NormalizeAttValue:DeRef --## Handler to normalize attribute values## Arguments:# opts parser options# ref entity reference## Results:# Returns characterproc xml::tclparser::NormalizeAttValue:DeRef {opts ref} { switch -glob -- $ref { #x* { scan [string range $ref 2 end] %x value set char [format %c $value] # Check that the char is legal for XML if {[regexp [format {^[%s]$} $::xml::Char] $char]} { return $char } else { return -code error "illegal character" } } #* { scan [string range $ref 1 end] %d value set char [format %c $value] # Check that the char is legal for XML if {[regexp [format {^[%s]$} $::xml::Char] $char]} { return $char } else { return -code error "illegal character" } } lt - gt - amp - quot - apos { array set map {lt < gt > amp & quot \" apos '} return $map($ref) } default { # A general entity. Must resolve to a text value - no element structure. array set options $opts upvar #0 $options(entities) map if {[info exists map($ref)]} { if {[regexp < $map($ref)]} { return -code error "illegal character \"<\" in attribute value" } if {![regexp & $map($ref)]} { # Simple text replacement return $map($ref) } # There are entity references in the replacement text. # Can't use child entity parser since must catch element structures return [NormalizeAttValue $opts $map($ref)] } elseif {[string compare $options(-entityreferencecommand) "::sgml::noop"]} { set result [uplevel #0 $options(-entityreferencecommand) [list $ref]] return $result } else { return -code error "unable to resolve entity reference \"$ref\"" } } }}# xml::tclparser::ParseEntity --## Parse general entity declaration## Arguments:# data text to parse## Results:# Tcl list containing entity declarationproc xml::tclparser::ParseEntity data { set data [string trim $data] if {[regexp $::sgml::ExternalEntityExpr $data discard type delimiter1 id1 discard delimiter2 id2 optNDATA ndata]} { switch $type { PUBLIC { return [list external $id2 $id1 $ndata] } SYSTEM { return [list external $id1 {} $ndata] } } } elseif {[regexp {^("|')(.*?)\1$} $data discard delimiter value]} { return [list internal $value] } else { return -code error "badly formed entity declaration" }}# xml::tclparser::delete --## Destroy parser data## Arguments:# name parser object## Results:# Parser data structure destroyedproc xml::tclparser::delete name { upvar \#0 [namespace current]::$name parser catch {::sgml::ParserDelete $parser(-statevariable)} catch {unset parser} return {}}# xml::tclparser::get --## Retrieve additional information from the parser## Arguments:# name parser object# method info to retrieve# args additional arguments for method## Results:# Depends on methodproc xml::tclparser::get {name method args} { upvar #0 [namespace current]::$name parser switch -- $method { elementdecl { switch [llength $args] { 0 { # Return all element declarations upvar #0 $parser(elementdecls) elements return [array get elements] } 1 { # Return specific element declaration upvar #0 $parser(elementdecls) elements if {[info exists elements([lindex $args 0])]} { return [array get elements [lindex $args 0]] } else { return -code error "element \"[lindex $args 0]\" not declared" } } default { return -code error "wrong number of arguments: should be \"elementdecl ?element?\"" } } } attlist { if {[llength $args] != 1} { return -code error "wrong number of arguments: should be \"get attlist element\"" } upvar #0 $parser(attlistdecls) return {} } entitydecl { } parameterentitydecl { } notationdecl { } default { return -code error "unknown method \"$method\"" } } return {}}# xml::tclparser::ExternalEntity --## Resolve and parse external entity## Arguments:# name parser object# base base URL# sys system identifier# pub public identifier## Results:# External entity is fetched and parsedproc xml::tclparser::ExternalEntity {name base sys pub} {}# xml::tclparser:: --## Reset a parser instance, ready to parse another document## Arguments:# name parser object## Results:# Variables unsetproc xml::tclparser::reset {name} { upvar \#0 [namespace current]::$name parser # Has this parser object been properly initialised? if {![info exists parser] || \ ![info exists parser(-name)]} { return [create $name] } array set parser { -final 1 depth 0 leftover {} } foreach var {Entities ExtEntities PEntities ExtPEntities ElDecls AttlistDecls NotDecls} { catch {unset [namespace current]::${var}$name} } # Initialise entities with predefined set array set [namespace current]::Entities$name [array get ::sgml::EntityPredef] return {}}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?