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 + -
显示快捷键?