Annotation of xmlschema/applyschema.py, revision 1.82

1.44      ht          1: # Copyright (C) 2000 LTG -- See accompanying COPYRIGHT and COPYING files
1.24      ht          2: # actually apply a schema to an instance
1.82    ! ht          3: # $Id: applyschema.py,v 1.81 2000/10/27 15:33:30 ht Exp $
1.58      ht          4: 
                      5: # TODO: enforce datatype constraints on xsi:type,
                      6: #   null, (noNamespace)schemaLocation
1.24      ht          7: 
1.63      ht          8: from PyLTXML import *
1.2       ht          9: from XML import *
1.58      ht         10: import os
1.41      ht         11: import XMLSchema
1.28      ht         12: import layer
1.3       aqw        13: import sys
1.4       richard    14: import re
1.18      ht         15: import xpath
1.20      ht         16: import types
1.41      ht         17: import string
1.53      ht         18: from urlparse import urljoin
1.58      ht         19: import tempfile
1.62      ht         20: import traceback
1.81      ht         21: import time
1.4       richard    22: 
                     23: whitespace = re.compile("^[ \t\r\n]*$")
1.74      richard    24: xsi = "http://www.w3.org/2000/10/XMLSchema-instance"
1.82    ! ht         25: vsraw="$Revision: 1.81 $ of $Date: 2000/10/27 15:33:30 $"
1.40      ht         26: vss=string.split(vsraw)
1.41      ht         27: vs="XSV %s/%s of %s %s"%(string.split(XMLSchema.versionString)[0],
1.40      ht         28:                          vss[1],vss[5],vss[6])
1.79      ht         29: dontWarn=1
1.5       richard    30: 
1.2       ht         31: def readXML(url):
1.67      ht         32:   if url:
                     33:     input = Open(url,
                     34:                  NSL_read|NSL_read_namespaces|NSL_read_defaulted_attributes)
                     35:   else:
                     36:     input = FOpen(sys.stdin,
                     37:                   NSL_read|NSL_read_namespaces|NSL_read_defaulted_attributes)
1.5       richard    38: #  item = GetNextQueryItem(input, ParseQuery(input.doctype, "."))
                     39: #  elem = Element(item, input.doctype)
1.58      ht         40:   try:
                     41:     elem = Element(input, 1)
                     42:   except:
                     43:     elem=None
                     44:   if elem:
                     45:     if input.doctype.encoding=='unknown':
                     46:       encoding=input.doctype.xencoding
                     47:     else:
                     48:       encoding=input.doctype.encoding
                     49:   else:
                     50:     encoding=None
1.2       ht         51:   Close(input)
1.58      ht         52:   return (elem,encoding)
1.2       ht         53: 
1.55      ht         54: def validate(element, typedef, schema, eltDecl):
1.58      ht         55:   if not hasattr(schema.factory,'errors'):
                     56:     schema.factory.errors=0
1.55      ht         57:   validateElement(element, typedef, schema, eltDecl)
1.33      ht         58:   return schema.factory.errors
1.2       ht         59: 
1.55      ht         60: def validateElement(element, type, schema, eltDecl=None):
1.4       richard    61:   global vel, vtype
                     62:   vel = element
                     63:   vtype = type
1.74      richard    64: #  print "validating element %s against %s" % (element.originalName, type)
1.47      richard    65:   if not eltDecl:
1.74      richard    66:     eqn=XMLSchema.QName(None,element.localName,element.namespaceName)
1.47      richard    67:     if s.vElementTable.has_key(eqn):
                     68:       eltDecl=s.vElementTable[eqn]
1.58      ht         69:   nullable = eltDecl and eltDecl.nullable # TODO: is this right if no eltDecl?
1.48      richard    70:   nulled = 0
1.74      richard    71:   if element.attributes.has_key((xsi, "null")):
1.48      richard    72:     if not nullable:
1.58      ht         73:       verror(element,
1.74      richard    74:              "xsi:null specified on non-nullable element %s" % element.originalName,
1.58      ht         75:              schema,"cvc-elt.1.1")
1.48      richard    76:       return
1.74      richard    77:     nulled = (element.attributes[(xsi, "null")].normalizedValue == "true")
                     78:   if element.attributes.has_key((xsi, "type")):
                     79:     t = element.attributes[(xsi, "type")].normalizedValue;
1.60      ht         80:     qt = XMLSchema.QName(t, element.nsdict)
1.57      ht         81:     if schema.vTypeTable.has_key(qt):
                     82:       xsitype=schema.vTypeTable[qt]
1.31      richard    83:     else:
1.58      ht         84:       verror(element,"xsi:type %s undefined" % qt,schema,"cvc-elt.2.2")
1.33      ht         85:       return
1.61      ht         86:     if type and not xsitype.isSubtype(type):
1.58      ht         87:       verror(element,
                     88:            "xsi:type %s is not a subtype of the declared type %s"%(qt,
                     89:                                                                    type.name),
                     90:              schema,"cvc-elt.2.3")
1.33      ht         91:       return
1.61      ht         92:     if type:
                     93:       vwarn(element,
                     94:             "using xsi:type %s instead of original %s" % (qt, type.name))
                     95:     else:
                     96:       vwarn(element,"using xsi:type %s" % qt)
1.33      ht         97:     type = xsitype
1.55      ht         98:   lax = not type
                     99:   # might have none in case of recursive call inside <any/>, or at top level
1.48      richard   100:   if nulled:
                    101:     return validateElementNull(element, type, schema)
1.55      ht        102:   if type:
1.58      ht        103:     # TODO: check type is not abstract
                    104:     if ((not type==XMLSchema.urType) and
                    105:         (isinstance(type, XMLSchema.AbInitio) or
                    106:          isinstance(type, XMLSchema.SimpleType))):
1.66      ht        107:       validateElementSimple(element, type, schema)
1.58      ht        108:       if eltDecl:
                    109:         validateKeys(eltDecl,element)
                    110:       return
                    111:     # a complexType
1.55      ht        112:     ad=type.attributeDeclarations
                    113:     ps=type.prohibitedSubstitutions
                    114:     et=type.elementTable
                    115:   else:
                    116:     ps=[]
                    117:     ad={}
                    118:     et={}
                    119:   assignAttributeTypes(element, ad, ps, schema, lax)
                    120:   validateAttributeTypes(element, element.attrTable, ad, schema)
1.74      richard   121: #  print "assigning types for %s" % element.originalName
                    122:   assignChildTypes(element.chunkedChildren, et, ps, schema, lax)
1.55      ht        123:   # we must look at the content model before checking the types, so that
                    124:   # we know which children matched <any>
                    125:   if type:
1.33      ht        126:     validateContentModel(element, type, schema)
1.74      richard   127:   validateChildTypes(element.chunkedChildren, schema, lax)
1.21      ht        128:   if eltDecl:
1.33      ht        129:     validateKeys(eltDecl,element)
1.2       ht        130: 
1.48      richard   131: def validateElementNull(element, type, schema):
1.74      richard   132:   if len(element.chunkedChildren) != 0:
                    133:     verror(element,"element %s is nulled but is not empty" % element.originalName,
1.58      ht        134:            schema,"cvc-elt.1.2.1")
                    135:   # TODO: should check for fixed value constraint
1.48      richard   136: 
1.2       ht        137: def validateElementSimple(element, type, schema):
                    138:   # check that:
1.47      richard   139:   #   it has no attributes (except xsi: ones)
1.2       ht        140:   #   it has one pcdata child, and if so
                    141:   #     the text of the pcdata matches the type
1.74      richard   142:   if element.attributes:
                    143:     for a in element.attributes.values():
                    144:       if a.namespaceName != xsi:
1.58      ht        145:         verror(element,
                    146:                "element {%s}%s with simple type not allowed attributes"%
1.74      richard   147:                (element.namespaceName, element.localName),
1.58      ht        148:                schema,"cvc-elt.4.1.1")
1.47      richard   149:         return
1.2       ht        150:   return validateTextModel(element, type, schema)
                    151: 
1.55      ht        152: def assignAttributeTypes(element, attrdefs, extendable, schema, lax):
1.2       ht        153:   # look up each attribute in attrdefs and assign its type
                    154:   # error if attr declaration is not found and type is not extendable
1.74      richard   155: #  print "assigning attrs for %s {%s}%s" % (element.originalName, element.namespaceName, element.localName)
1.33      ht        156:   element.attrTable={}
1.74      richard   157:   for a in element.attributes.values():
                    158: #    print "assigning attr %s {%s}%s" % (a.originalName, a.namespaceName, a.localName)
                    159:     an=XMLSchema.QName(None,a.localName,a.namespaceName)
1.33      ht        160:     element.attrTable[an]=a
1.74      richard   161:     if a.namespaceName == xsi:
                    162:       if a.localName not in ('type','null','schemaLocation','noNamespaceSchemaLocation'):
1.58      ht        163:         verror(element,"unknown xsi attribute %s" % an,schema,
                    164:                "cvc-complex-type.1.3")
1.27      richard   165:     elif attrdefs.has_key(an):
1.43      ht        166:       a.type = attrdefs[an].attributeDeclaration
1.55      ht        167:     elif lax:
1.74      richard   168:       if a.namespaceName and schema.vAttributeTable.has_key(an):
1.55      ht        169:         a.type=schema.vAttributeTable[an]
                    170:       else:
                    171:         a.type=None
1.43      ht        172:     elif (attrdefs.has_key("#any") and
1.74      richard   173:           attrdefs["#any"].attributeDeclaration.allows(a.namespaceName)):
1.43      ht        174:       a.type = attrdefs["#any"].attributeDeclaration
1.2       ht        175:     else:
1.58      ht        176:       verror(element,"undeclared attribute %s" % an,schema,
                    177:                "cvc-complex-type.1.3")
1.2       ht        178:       a.type = None
1.33      ht        179:   return
1.2       ht        180: 
1.33      ht        181: def validateAttributeTypes(element,attrs, attrdefs, schema):
1.2       ht        182:   # check that each attribute matches its type
                    183:   # check that all required attributes are present
1.80      ht        184:   # TODO: add defaulted attributes (shouldn't need to check their types)
                    185:   #       checked fixed values
1.33      ht        186:   for (adq,ad) in attrdefs.items():
                    187:     if ad.minOccurs==1 and not attrs.has_key(adq):
1.58      ht        188:       verror(element,"required attribute %s not present"%adq,schema,
                    189:              'cvc-complex-type.1.4')
1.33      ht        190:   for (an,a) in attrs.items():
                    191:     if an.uri!=xsi and a.type:
1.43      ht        192:       if isinstance(a.type,XMLSchema.Wildcard):
                    193:         res=a.type.validate(a,schema,'attribute',element)
                    194:       else:
1.58      ht        195:         if a.type.typeDefinition:
1.74      richard   196:           res=a.type.typeDefinition.validateText(a.normalizedValue,element, schema)
1.80      ht        197:           if a.type.valueConstraint and a.type.valueConstraint[0]=='fixed':
                    198:             if a.normalizedValue!=a.type.valueConstraint[1]:
                    199:               verror(element,"fixed value did not match for attribute %s: %s!=%s"%(an,a.normalizedValue,a.type.valueConstraint[1]),schema,"cvc-attribute.1.3")
1.58      ht        200:         else:
                    201:           res=None
1.33      ht        202:       if res:
                    203:         verror(element,"attribute type check failed for %s: %s%s"%(an,
1.74      richard   204:                                                                    a.normalizedValue,
1.33      ht        205:                                                                    res),
1.58      ht        206:                schema,'cvc-attribute.1.2')
1.2       ht        207: 
1.55      ht        208: def assignChildTypes(children, elementTable, extendable, schema, lax):
1.2       ht        209:   # look up each child tag and record the type
                    210:   # (it may not be an error if it is not declared; we don't know that
                    211:   #  until we see what it matches in the content model)
                    212:   for child in children:
1.58      ht        213:     if isinstance(child,Element):
1.74      richard   214:       qname = XMLSchema.QName(None,child.localName,child.namespaceName)
1.10      richard   215:       if elementTable.has_key(qname):
1.82    ! ht        216:         decl=elementTable[qname]
        !           217:         try:
        !           218:           child.type = decl.typeDefinition
        !           219:         except:
        !           220:           print decl
        !           221:         child.eltDecl = decl
1.74      richard   222:       elif lax and child.namespaceName and schema.vElementTable.has_key(qname):
1.82    ! ht        223:         decl=schema.vElementTable[qname]
        !           224:         child.type=decl.typeDefinition
        !           225:         child.eltDecl=decl
1.2       ht        226:       else:
                    227:        child.type = None
1.82    ! ht        228:         child.eltDecl=None
1.2       ht        229:   return 1
                    230: 
                    231: def validateContentModel(element, type, schema):
                    232:   # trace a path through the content model
                    233:   # if a child matches an <any tag=... type=...> we need to indicate
                    234:   # that that child should be validated with its xsd:type if it has one
                    235:   # if a child matches some other kind of <any> we need to indicate
                    236:   # that it's not an error if we can't find its type
                    237: 
1.74      richard   238: #  print "validating model for %s content %s" % (element.originalName, type.content)
1.33      ht        239:   if type.contentType == "empty":
                    240:     validateEmptyModel(element, type, schema)
                    241:   elif type.contentType == "textOnly":
                    242:     validateTextModel(element, type.model, schema)
                    243:   else:
                    244:     validateElementModel(element, type.fsm,
                    245:                          type.contentType == "mixed", schema)
1.2       ht        246: 
                    247: def validateEmptyModel(element, type, schema):
1.74      richard   248:   if len(element.chunkedChildren) != 0:
                    249:     verror(element,"element %s must be empty but is not" % element.originalName,schema,
1.58      ht        250:            "cvc-complex-type.1.2")
1.2       ht        251: 
                    252: def validateTextModel(element, type, schema):
                    253:   # check that:
                    254:   #   it has one pcdata child, and if so
                    255:   #     the text of the pcdata matches the type
1.74      richard   256:   name = element.originalName
1.58      ht        257:   n=0
1.74      richard   258:   for child in element.chunkedChildren:
1.58      ht        259:     if isinstance(child,Pcdata):
                    260:       n=1
                    261:     elif isinstance(child,Element):
                    262:       verror(element,
                    263:              "element {%s}%s with simple type not allowed element children"%
1.74      richard   264:              (element.namespaceName,name),schema,"cvc-complex-type.1.2.2")
1.66      ht        265:       # TODO: mark this (and any others) as not validated
1.62      ht        266:       return
1.2       ht        267:   else:
                    268:     if n == 0:
                    269:       text = ""
                    270:     else:
1.74      richard   271:       text = element.chunkedChildren[0].characters
1.58      ht        272:     res=type.validateText(text, element, schema)
1.33      ht        273:     if res:
                    274:       verror(element,"element content failed type check: %s%s"%(text,res),
1.58      ht        275:              schema,"cvc-complex-type.1.2.2")
1.2       ht        276: 
1.4       richard   277: def validateElementModel(element, fsm, mixed, schema):
1.74      richard   278:   #  print "validating element model for %s" % element.originalName
1.4       richard   279:   n = fsm.startNode
1.74      richard   280:   for c in element.chunkedChildren:
1.58      ht        281:     if isinstance(c,Pcdata):
1.74      richard   282:       if (not mixed) and (not whitespace.match(c.characters)):
1.58      ht        283:        verror(c,
                    284:                "text not allowed in element %s: |%s|" %
1.74      richard   285:                (element.originalName,c.characters),
1.58      ht        286:                schema,"cvc-complex-type.1.2.3")
1.33      ht        287:        return
1.58      ht        288:     elif isinstance(c,Element):
1.74      richard   289:       qname = XMLSchema.QName(None, c.localName, c.namespaceName)
1.8       richard   290:       next = None
1.13      richard   291:       anynext = None
1.4       richard   292:       for e in n.edges:
1.10      richard   293:         if e.label == qname:
1.8       richard   294:          next = e.dest
1.4       richard   295:          break
1.43      ht        296:         if isinstance(e.label, XMLSchema.Wildcard):
1.74      richard   297:           if e.label.allows(c.namespaceName):
1.41      ht        298:             anynext = e.dest
                    299:             anylab = e.label
1.8       richard   300:       if not next:
1.13      richard   301:         if anynext:
                    302:           n = anynext
1.17      richard   303: # this is no longer an error, but something more complicated is XXX
                    304: #          if c.type:
                    305: #            where(child.where)
                    306: #            print "element matched <any> but had a type assigned"
                    307: #            v = 0
                    308: #          else:
                    309: #            c.type = "<any>"
1.33      ht        310:           c.type = anylab
1.13      richard   311:         else:
1.58      ht        312:           verror(c,
                    313:                  "element %s not allowed here in element %s:\n"%
1.74      richard   314:                  (qname, XMLSchema.QName(None,element.localName,element.namespaceName)),
1.58      ht        315:                  schema,"cvc-complex-type.1.2.4",0,fsm.asXML())
1.13      richard   316:       else:
                    317:         n = next
1.4       richard   318:   if not n.isEndNode:
1.58      ht        319:     verror(element,
                    320:            "content of %s is not allowed to end here:\n"%
1.74      richard   321:            element.originalName,
1.58      ht        322:            schema,"cvc-complex-type.1.2.4",1,fsm.asXML())
1.33      ht        323:   return
1.2       ht        324: 
1.55      ht        325: def validateChildTypes(children, schema, lax):
1.2       ht        326:   # validate each child element against its type, if we know it
                    327:   # report an error if we don't know it and it's not in <any>
1.7       richard   328:   v = 1
1.2       ht        329:   for child in children:
1.58      ht        330:     if isinstance(child,Element):
1.33      ht        331:       if child.type:
1.82    ! ht        332:         if child.eltDecl:
        !           333:           validateElement(child,child.type,schema,child.eltDecl)
        !           334:         else:
        !           335:           # child.type is actually a wildcard
        !           336:           child.type.validate(child,schema,'element',child)
1.55      ht        337:       elif lax:
1.82    ! ht        338:         # TODO: check that this branch ever happens at all
1.58      ht        339:         # TODO: record impact of missing type in PSVI
1.55      ht        340:         validateElement(child,None,schema) # will be lax because no type
1.2       ht        341:       else:
1.33      ht        342:        verror(child,
1.58      ht        343:                "undeclared element %s"%
1.74      richard   344:                XMLSchema.QName(None,child.localName,child.namespaceName),
1.58      ht        345:                schema,"src-resolve")
1.2       ht        346: 
1.21      ht        347: def validateKeys(decl,elt):
1.22      ht        348:   elt.keyTabs={}
1.33      ht        349:   validateKeys1(elt,decl.keys,1)
                    350:   validateKeys1(elt,decl.uniques,0)
                    351:   validateKeyRefs(elt,decl.keyrefs)
1.22      ht        352: 
                    353: def validateKeys1(elt,kds,reqd):
                    354:   for key in kds:
1.21      ht        355:     tab={}
                    356:     sp=xpath.XPath(key.selector)
1.24      ht        357:     candidates=sp.find(elt)
1.21      ht        358:     if candidates:
1.69      ht        359:       fps=map(lambda f:xpath.XPath(f),key.fields)
1.21      ht        360:       for s in candidates:
1.22      ht        361:         keyKey=buildKey(s,fps)
1.59      ht        362:         if keyKey:
                    363:           if len(keyKey)>1:
                    364:             keyKey=tuple(keyKey)
                    365:           else:
                    366:             keyKey=keyKey[0]
                    367:         else:
                    368:           if reqd:
                    369:             verror(s,
1.69      ht        370:                    "missing one or more fields %s from key %s"%(key.fields,
1.59      ht        371:                                                                 key.name),
                    372:                    key.schema,"cvc-identity-constraint.2.2.2")
1.22      ht        373:           break
1.21      ht        374:        if tab.has_key(keyKey):
1.58      ht        375:           if reqd:
                    376:             code="cvc-identity-constraint.2.2.3"
                    377:           else:
                    378:             code="cvc-identity-constraint.2.1.2"
                    379:          verror(s,"duplicate key %s, first appearance was %s"%
                    380:                  (str(keyKey),
                    381:                   XMLSchema.whereString(tab[keyKey].where)),
                    382:                  key.schema,code)
1.21      ht        383:        else:
                    384:          tab[keyKey]=s
1.22      ht        385:     elt.keyTabs[key.name]=tab
                    386: 
                    387: def buildKey(s,fps):
                    388:   keyKey=[]
                    389:   for fp in fps:
1.24      ht        390:     kv=fp.find(s)
1.22      ht        391:     if kv:
                    392:       if len(kv)>1:
1.58      ht        393:         # TODO error or shouldnt?
1.33      ht        394:         vwarn(s,"oops, multiple field hits for %s at %s: %s"%(fp.str,s,kv))
1.22      ht        395:       if isinstance(kv[0],Element):
1.74      richard   396:         if (len(kv[0].chunkedChildren)>0 and
                    397:             isinstance(kv[0].chunkedChildren[0],Pcdata)):
                    398:           keyKey.append(kv[0].chunkedChildren[0].characters)
1.22      ht        399:         else:
                    400:           # XPath says in this case value is the empty string
                    401:           pass
1.54      ht        402:       elif somestring(type(kv[0])):
1.22      ht        403:         keyKey.append(kv[0])
                    404:       else:
1.58      ht        405:         # TODO error or shouldnt?
1.33      ht        406:         vwarn(s,"oops, key value %s:%s"%(type(kv[0]),kv[0]))
1.22      ht        407:     else:
                    408:       return None
                    409:   return keyKey
                    410: 
                    411: def validateKeyRefs(elt,krds):
                    412:   res=1
                    413:   for ref in krds:
1.25      ht        414:     if elt.keyTabs.has_key(ref.refer):
                    415:       keyTab=elt.keyTabs[ref.refer]
                    416:       if keyTab=='bogus':
                    417:        break
                    418:     else:
                    419:       elt.keyTabs[ref.refer]='bogus'
1.52      richard   420:       verror(elt,
1.33      ht        421:              "No key or unique constraint named %s declared, refed by keyref %s"%(ref.refer,ref.name),
1.58      ht        422:              ref.schema,"cvc-identity-constraint.2.3.2")
1.25      ht        423:       break
1.22      ht        424:     sp=xpath.XPath(ref.selector)
1.24      ht        425:     candidates=sp.find(elt)
1.22      ht        426:     if candidates:
1.69      ht        427:       fps=map(lambda f:xpath.XPath(f),ref.fields)
1.22      ht        428:       for s in candidates:
                    429:         keyKey=buildKey(s,fps)
                    430:         if not keyKey:
                    431:           break
                    432:        if len(keyKey)>1:
                    433:          keyKey=tuple(keyKey)
                    434:        else:
                    435:          keyKey=keyKey[0]
1.25      ht        436:        if not keyTab.has_key(keyKey):
1.58      ht        437:          verror(s,"no key in %s for %s"%(ref.refer,str(keyKey)),ref.schema,
                    438:                  "cvc-identity-constraint.2.3.2")
1.21      ht        439: 
1.58      ht        440: def findSchemaLocs(element,schema):
1.30      richard   441:   pairs = []
1.74      richard   442:   for a in element.attributes.values():
                    443:     if a.namespaceName == xsi:
                    444:       if a.localName == "schemaLocation":
                    445:         scls=string.split(a.normalizedValue)
1.43      ht        446:         while scls:
1.58      ht        447:           if len(scls)>1:
                    448:             pairs.append((scls[0], scls[1]))
                    449:           else:
1.74      richard   450:             verror(element,"xsi:schemaLocation must be a list with an even number of members: %s"%string.split(a.normalizedValue),schema,"???")
1.43      ht        451:           scls=scls[2:]
1.74      richard   452:       elif a.localName == "noNamespaceSchemaLocation":
                    453:         pairs.append((None,a.normalizedValue))
                    454:   for c in element.chunkedChildren:
1.30      richard   455:     if isinstance(c, Element):
1.58      ht        456:       scl=findSchemaLocs(c,schema)
1.43      ht        457:       if scl:
                    458:         pairs = pairs + scl
1.30      richard   459:   return pairs
                    460:   
1.81      ht        461: def runitAndShow(en,rns=[],k=0,style=None,enInfo=None,outfile=None,dw=1,
                    462:                  timing=0):
1.79      ht        463:   global dontWarn
                    464:   dontWarn=dw
1.81      ht        465:   if timing:
                    466:     timing=time.time()
                    467:   (res,encoding,errs)=runit(en,rns,k,timing)
                    468:   if timing:
                    469:     sys.stderr.write("Finished:         %6.2f\n"%(time.time()-timing))
1.58      ht        470:   if not encoding:
                    471:     encoding='UTF-8'
1.75      ht        472:   if outfile:
                    473:     try:
                    474:       outf=open(outfile,"w")
                    475:     except:
                    476:       sys.stderr.write("couldn't open %s for output, falling back to stderr"%
                    477:                        outfile)
                    478:       outf=sys.stderr
                    479:   else:
                    480:     outf=sys.stderr
                    481:   errout=OpenStream(outf,
1.58      ht        482:                     CharacterEncodingNames[encoding],
                    483:                     NSL_write+NSL_write_plain)
                    484:   if encoding!='UTF-8':
                    485:     es=" encoding='%s'"%encoding
                    486:   else:
                    487:     es=""
1.75      ht        488:   PrintTextLiteral(errout,"<?xml version='1.0'%s?>\n"%es)
1.58      ht        489:   if style:
1.75      ht        490:     PrintTextLiteral(errout,
                    491:                      "<?xml-stylesheet type='text/xsl' href='%s'?>\n"%style)
1.64      ht        492:   if enInfo:
                    493:     for (k,v) in enInfo.items():
                    494:       res.addAttr(k,v)
1.78      ht        495:   if errs:
1.76      ht        496:     res.addAttr("crash","true")
1.58      ht        497:   res.printme(errout)
1.75      ht        498:   PrintTextLiteral(errout,"\n")
1.58      ht        499:   Close(errout)
1.78      ht        500:   if errs:
                    501:     return string.join(map(lambda es:string.join(es,''),errs),'')
1.76      ht        502:   else:
                    503:     return
                    504: 
                    505: class SchemaValidationError(Exception):
                    506:   def __init__(self,arg):
                    507:     Exception.__init__(self,arg)
1.58      ht        508: 
1.81      ht        509: def runit(en,rns=[],k=0,timing=0):
1.78      ht        510:   global s,e,t,f,res,ed,btlist
                    511:   btlist=[]
1.33      ht        512: 
1.45      ht        513:   ss = s = None
1.33      ht        514: 
1.41      ht        515:   f=XMLSchema.newFactory()
1.58      ht        516:   f.errors=0
1.36      ht        517:   base=f.fileNames[0]
1.67      ht        518:   if en:
                    519:     ren=urljoin(base,en)
                    520:   else:
                    521:     ren=None
1.30      richard   522: 
1.58      ht        523:   res=Element("xsv")
                    524:   f.resElt=res
                    525:   res.addAttr("xmlns","http://www.w3.org/2000/05/xsv")
                    526:   res.addAttr("version",vs)
1.67      ht        527:   res.addAttr("target",ren or "[stdin]")
1.58      ht        528:   if rns:
                    529:     res.addAttr("schemaDocs",string.join(rns,' '))
                    530: 
                    531:   rdn=tempfile.mktemp("xsverrs")
                    532:   redirect=open(rdn,"w+")
                    533:   savedstderr=os.dup(2)                        # save stderr
                    534:   os.dup2(redirect.fileno(),2)
                    535:   try:
                    536:     (e,encoding)=readXML(ren)
1.81      ht        537:     if timing:
                    538:       os.write(savedstderr,"target read:      %6.2f\n"%(time.time()-timing))
1.63      ht        539:   except LTXMLinter.error:
1.78      ht        540:     pfe=Element("bug")
                    541:     pfe.children=[Pcdata("validator crash during target reading")]
                    542:     res.children.append(pfe)
1.58      ht        543:     e=None
                    544:     encoding=None
                    545:   if not e:
                    546:     res.addAttr('outcome',"validation not attempted")
                    547:     sys.stderr.flush()
                    548:     registerRawErrors(redirect,res)
                    549:     # put stderr back
                    550:     os.dup2(savedstderr,2)
1.78      ht        551:     return (res,None,btlist)
1.58      ht        552: 
                    553:   # TODO: check each schema doc against schema for schemas, if possible,
                    554:   # unless caller explicitly opts out (?)
1.28      ht        555:   if rns:
1.49      ht        556:     try:
1.53      ht        557:       s = XMLSchema.fromFile(urljoin(base,rns[0]),f)
1.81      ht        558:       if timing:
                    559:         os.write(savedstderr,"schema read:      %6.2f\n"%(time.time()-timing))
1.78      ht        560:     except:
                    561:       pfe=Element("bug")
                    562:       pfe.children=[Pcdata("validator crash during schema reading")]
                    563:       res.children.append(pfe)
                    564:       btlist.append(traceback.format_exception(sys.exc_type,
                    565:                                                sys.exc_value,
                    566:                                                sys.exc_traceback))
1.30      richard   567:     for rn in rns[1:]:
1.49      ht        568:       try:
1.67      ht        569:         ffr=XMLSchema.fromFile(urljoin(base,rn),f)
1.81      ht        570:         if timing:
                    571:           os.write(savedstderr,"schema read:      %6.2f\n"%(time.time()-timing))
1.67      ht        572:         ss=ss or ffr
1.78      ht        573:       except:
                    574:         pfe=Element("bug")
                    575:         pfe.children=[Pcdata("validator crash during schema reading")]
                    576:         res.children.append(pfe)
                    577:         btlist.append(traceback.format_exception(sys.exc_type,
                    578:                                                  sys.exc_value,
                    579:                                                  sys.exc_traceback))
1.30      richard   580: 
1.45      ht        581:   if not s:
1.65      ht        582:     if ss:
                    583:       s=ss
                    584:     else:
                    585:       s = XMLSchema.Schema(f,None)
                    586:       s.targetNS='##dummy'
1.45      ht        587: 
1.58      ht        588:   schemaLocs = findSchemaLocs(e,s)
                    589:   res.addAttr('schemaLocs',join(map(lambda p:"%s -> %s"%(p[0] or 'None',p[1]),
                    590:                                     schemaLocs),
                    591:                                 '; '))
1.30      richard   592:   for (ns, sl) in schemaLocs:
1.49      ht        593:     try:
1.67      ht        594:       XMLSchema.checkinSchema(f, ns, sl,e,ren or "[stdin]")
1.81      ht        595:       if timing:
                    596:         os.write(savedstderr,"schema read:      %6.2f\n"%(time.time()-timing))
1.78      ht        597:     except:
                    598:       pfe=Element("bug")
                    599:       pfe.children=[Pcdata("validator crash during schema reading")]
                    600:       res.children.append(pfe)
                    601:       btlist.append(traceback.format_exception(sys.exc_type,
                    602:                                                sys.exc_value,
                    603:                                                sys.exc_traceback))
1.30      richard   604:   
1.74      richard   605:   res.addAttr('docElt',"{%s}%s"%(e.namespaceName,e.localName))
                    606:   if (e.namespaceName and
                    607:       (e.namespaceName not in ('http://www.w3.org/XML/1998/namespace',
                    608:                    'http://www.w3.org/2000/10/XMLSchema-instance')) and
                    609:       not f.schemas.has_key(e.namespaceName)):
1.34      ht        610:     try:
1.74      richard   611:       XMLSchema.checkinSchema(f,e.namespaceName,e.namespaceName,e,ren or "[stdin]")
1.81      ht        612:       if timing:
                    613:         os.write(savedstderr,"schema read:      %6.2f\n"%(time.time()-timing))
1.58      ht        614:       res.addAttr('nsURIDeref','success')
1.78      ht        615:     except:
                    616:       pfe=Element("bug")
                    617:       pfe.children=[Pcdata("validator crash during schema reading")]
                    618:       res.children.append(pfe)
                    619:       btlist.append(traceback.format_exception(sys.exc_type,
                    620:                                                sys.exc_value,
                    621:                                                sys.exc_traceback))
1.58      ht        622:       res.addAttr('nsURIDeref','failure')
1.30      richard   623:     
1.58      ht        624:   sys.stderr.flush()
                    625:   registerRawErrors(redirect,res)
                    626:   # put stderr back
                    627:   os.dup2(savedstderr,2)
                    628: 
                    629:   try:
                    630:     ecount=XMLSchema.prepare(f)
1.81      ht        631:     if timing:
                    632:       sys.stderr.write("schemas prepared: %6.2f\n"%(time.time()-timing))
1.58      ht        633:   except:
                    634:     ecount=-1
1.78      ht        635:     btlist.append(traceback.format_exception(sys.exc_type,
                    636:                                              sys.exc_value,
                    637:                                              sys.exc_traceback))
1.58      ht        638:     pfe=Element("bug")
1.76      ht        639:     pfe.children=[Pcdata("validator crash during factory preparation")]
1.58      ht        640:     res.children.append(pfe)
1.76      ht        641: 
1.58      ht        642:   kgm="true"
                    643:   kg=1
1.33      ht        644:   if ecount:
1.58      ht        645:     if ecount<0:
                    646:       kg=0
1.33      ht        647:     else:
1.58      ht        648:       if not k:
                    649:         kg=0
                    650:     if not kg:
                    651:      kgm="false"
                    652:   res.addAttr('instanceAssessed',kgm)
                    653:   if not kg:
1.82    ! ht        654:     if ecount<0:
        !           655:       ecount=0
        !           656:       for sch in f.schemas.values():
        !           657:         ecount=ecount+sch.errors
        !           658:     res.addAttr('schemaErrors',str(ecount))
1.78      ht        659:     return (res,encoding,btlist)
1.30      richard   660: 
1.74      richard   661:   cl=string.find(':',e.originalName)
1.28      ht        662:   if cl>-1:
1.74      richard   663:     prefix=e.originalName[0:cl]
1.28      ht        664:   else:
                    665:     prefix=''
1.74      richard   666:   eltname = XMLSchema.QName(prefix,e.localName,e.namespaceName)
1.30      richard   667: 
                    668:   if not s:
                    669:     # any one will do
1.33      ht        670:     s = f.sfors
                    671:   t=None
                    672:   
1.55      ht        673:   ed=None
1.33      ht        674:   if s and s.vElementTable.has_key(eltname):
1.55      ht        675:     ed=s.vElementTable[eltname]
                    676:     t=ed.typeDefinition
1.58      ht        677:   if t:
                    678:     if t.name:
1.66      ht        679:       if hasattr(t,'qname'):
                    680:         tn=t.qname.string()
                    681:       else:
                    682:         tn=t.name
1.58      ht        683:     else:
                    684:       tn='[Anonymous]'
                    685:     res.addAttr('rootType',tn)
                    686:     res.addAttr('validation','strict')
                    687:   else:
                    688:     res.addAttr('validation','lax')
1.33      ht        689: 
                    690:   if e and s:
1.76      ht        691: 
                    692:     try:
                    693:       validate(e, t, s, ed)
                    694:     except:
1.78      ht        695:       btlist.append(traceback.format_exception(sys.exc_type,
                    696:                                                sys.exc_value,
                    697:                                                sys.exc_traceback))
1.76      ht        698:       pfe=Element("bug")
                    699:       pfe.children=[Pcdata("validator crash during validation")]
                    700:       res.children.append(pfe)
1.58      ht        701:     res.addAttr('instanceErrors',str(s.factory.errors))
1.77      ht        702:     ec=0
                    703:     for sch in f.schemas.values():
                    704:       ec=ec+sch.errors
                    705:     res.addAttr('schemaErrors',str(ec))
1.78      ht        706:     return (res,encoding,btlist)
1.30      richard   707: 
1.58      ht        708: def registerRawErrors(redirect,res):
                    709:   if redirect.tell(): 
                    710:     redirect.seek(0)
                    711:     ro=Element("XMLMessages")
                    712:     o="\n%s"%redirect.read()
                    713:     ro.children=[Pcdata(o)]
                    714:     res.children.append(ro)
                    715:   redirect.close()
                    716: 
                    717: def verror(elt,message,schema,code=None,two=0,daughter=None):
                    718:   # code argument identifies CVC
                    719:   ve=Element("invalid")
                    720:   ve.children=[Pcdata(message)]
                    721:   if code:
                    722:     ve.addAttr("code",code)
1.33      ht        723:   if two:
1.58      ht        724:     XMLSchema.where(ve,elt.where2)
1.33      ht        725:   else:
1.58      ht        726:     XMLSchema.where(ve,elt.where)
                    727:   if daughter:
                    728:     ve.children.append(daughter)
                    729:   res.children.append(ve)
1.33      ht        730:   schema.factory.errors=schema.factory.errors+1
                    731: 
                    732: def vwarn(elt,message):
1.79      ht        733:   if dontWarn:
                    734:     return
1.58      ht        735:   ve=Element("warning")
                    736:   ve.children=[Pcdata(message)]
1.33      ht        737:   if elt:
1.58      ht        738:     XMLSchema.where(ve,elt.where)
                    739:   res.children.append(ve)
1.24      ht        740: 
1.41      ht        741: # validation methods for schema components
                    742: 
1.43      ht        743: def av(self,child,schema,kind,elt):
1.74      richard   744:   q = XMLSchema.QName(None,child.localName,child.namespaceName)
1.43      ht        745:   vwarn(elt,"allowing %s because it matched wildcard(%s)" %
                    746:         (q,self.allowed))
                    747:   if self.processContents!='skip':
1.74      richard   748:     if schema.factory.schemas.has_key(child.namespaceName):
1.41      ht        749:       # only try if we might win -- needs work
                    750:       try:
1.43      ht        751:         if kind=='element':
                    752:           e = schema.vElementTable[q]
                    753:         else:
                    754:           e = schema.vAttributeTable[q]
1.41      ht        755:       except KeyError:
                    756:         e=None
1.58      ht        757:       if e and e.typeDefinition:
1.43      ht        758:         vwarn(None,"validating it against %s" %
                    759:               (e.typeDefinition.name or 'anonymous type'))
                    760:         if kind=='element':
                    761:           validateElement(child, e.typeDefinition, schema)
                    762:         else:
1.78      ht        763:           return e.typeDefinition.validateText(child.normalizedValue,
                    764:                                                elt, schema)
1.61      ht        765:       elif (self.processContents=='strict' and
1.74      richard   766:             not (kind=='element' and child.attributes.has_key((xsi, "type")))):
1.58      ht        767:         # TODO check this against actual def'n of missing component
1.43      ht        768:         verror(elt,
                    769:                "can't find a type for wildcard-matching %s %s" %(kind, q),
1.58      ht        770:                schema,
                    771:                "src-resolve")
1.61      ht        772:       elif kind=='element':
                    773:         vwarn(None,"validating it laxly")
                    774:         validateElement(child,None,schema)
1.43      ht        775: 
                    776: XMLSchema.Wildcard.validate=av
1.42      ht        777: 
1.43      ht        778: def tv(self,child,schema,kind,elt):
1.42      ht        779:   validateElement(child, self, schema)
1.41      ht        780: 
1.43      ht        781: XMLSchema.Type.validate=XMLSchema.AbInitio.validate=tv
1.41      ht        782: 
1.58      ht        783: def validateText(self, text, context, schema):
                    784:   if self==XMLSchema.urType:
                    785:     return
                    786:   else:
1.69      ht        787:     if self.variety=='atomic':
                    788:       # ref may have failed
                    789:       return (self.primitiveType and
                    790:               self.primitiveType.checkString(text,context))
                    791:     elif self.variety=='list':
                    792:       it=self.itemType
1.58      ht        793:       # TODO: what about post-list facets?
1.70      ht        794:       if not it:
                    795:         return
1.58      ht        796:       for substr in string.split(text):
1.69      ht        797:         res=it.validateText(substr,context,schema)
1.58      ht        798:         if res:
                    799:           return res+' in list'
                    800:       return
1.69      ht        801:     elif self.variety=='union':
                    802:       mts=self.memberTypes
                    803:       subres=[]
                    804:       # TODO: what about post-union facets?
                    805:       for mt in mts:
1.70      ht        806:         if mt:
                    807:           res=mt.validateText(text,context,schema)
                    808:           if res:
                    809:             subres.append(res)
                    810:           else:
                    811:             # bingo
                    812:             return
1.69      ht        813:       # no subtypes won, we lose
1.70      ht        814:       return " no members of union succeeded: %s"%subres
1.58      ht        815:     else:
1.69      ht        816:       XMLSchema.shouldnt('vv '+str(self.variety))
1.58      ht        817: 
                    818: XMLSchema.SimpleType.validateText=validateText
                    819: 
                    820: def validateText(self, text, context, schema):
                    821:     return self.checkString(text,context)
                    822: 
                    823: XMLSchema.AbInitio.validateText=validateText
                    824: 
1.71      richard   825: # checkString methods
                    826: 
                    827: def checkString(self,str,context):
                    828:   # TODO: rethink allowedFacets: not efficient
                    829:   if 'enumeration' in self.allowedFacets and self.enumeration!=None:
                    830:     for val in self.enumeration:
                    831:       if val==str:
                    832:         return
                    833:     return " not in enumeration %s"%self.enumeration
                    834: 
                    835: XMLSchema.AbInitio.checkString = checkString
                    836: 
                    837: def checkString(self,str,context):
                    838:   try:
                    839:     if ('.' in str) or ('E' in str):
                    840:       val=string.atof(str)
                    841:     else:
                    842:       val=string.atoi(str)
                    843:   except ValueError:
                    844:     return " does not represent a number"
                    845:   if self.minInclusive!=None and val<self.minInclusive:
                    846:     return "<%d"%self.minInclusive
                    847:   if self.minExclusive!=None and val<=self.minExclusive:
                    848:     return "<=%d"%self.minExclusive
                    849:   if self.maxInclusive!=None and val>self.maxInclusive:
                    850:     return ">%d"%self.maxInclusive
                    851:   if self.maxExclusive!=None and val>=self.maxExclusive:
                    852:     return ">=%d"%self.maxExclusive
1.72      richard   853:   return XMLSchema.AbInitio.checkString(self,str,context)
1.71      richard   854: 
                    855: XMLSchema.DecimalST.checkString = checkString
                    856: 
                    857: def checkString(self,str,context):
                    858:   # not complete by any means
                    859:   parts=string.split(str,':')
                    860:   if len(parts)>2:
                    861:     return " has more than one colon"
                    862:   if len(parts)==2 and not context.nsdict.has_key(parts[0]):
                    863:     return " has undeclared prefix: %s"%parts[0]
1.72      richard   864:   return XMLSchema.AbInitio.checkString(self,str,context)
1.71      richard   865: 
                    866: XMLSchema.QNameST.checkString = checkString
1.58      ht        867: 
1.42      ht        868: # run at import if top
                    869: 
                    870: if __name__=='__main__':
                    871:   argl=sys.argv[1:]
                    872:   k=0
1.79      ht        873:   dw=1
1.81      ht        874:   timing=0
1.58      ht        875:   style=None
1.75      ht        876:   outfile=None
1.42      ht        877:   while argl:
                    878:     if argl[0]=='-k':
                    879:       k=1
1.58      ht        880:     elif argl[0]=='-s':
                    881:       style=argl[1]
                    882:       argl=argl[1:]
1.75      ht        883:     elif argl[0]=='-o':
                    884:       outfile=argl[1]
                    885:       argl=argl[1:]
1.79      ht        886:     elif argl[0]=='-w':
                    887:       dw=0
1.81      ht        888:     elif argl[0]=='-t':
                    889:       timing=1
1.75      ht        890:     elif argl[0][0]=='-':
1.81      ht        891:       sys.stderr.write("Usage: [-ktw] [-s stylesheet] [-o outputFile] file [schema1 schema2 . . .]\n")
1.75      ht        892:       sys.exit(-1)
1.42      ht        893:     else:
                    894:       break
                    895:     argl=argl[1:]
                    896: 
                    897:   if argl:
1.81      ht        898:     res=runitAndShow(argl[0],argl[1:],k,style,None,outfile,dw,timing)
1.42      ht        899:   else:
1.81      ht        900:     res=runitAndShow(None,[],k,style,None,outfile,dw,timing)
1.76      ht        901: 
                    902:   if res:
                    903:     raise SchemaValidationError,res
1.41      ht        904: 
1.25      ht        905: # $Log: applyschema.py,v $
1.82    ! ht        906: # Revision 1.81  2000/10/27 15:33:30  ht
        !           907: # Output timing info if -t on command line
        !           908: #
1.81      ht        909: # Revision 1.80  2000/10/18 15:54:58  ht
                    910: # make effort to check 'fixed' attribute values
                    911: #
1.80      ht        912: # Revision 1.79  2000/10/17 13:35:41  ht
                    913: # put switch on warnings, default is don't
                    914: #
1.79      ht        915: # Revision 1.78  2000/10/17 12:45:15  ht
                    916: # try to catch and log all crashes
                    917: # replace stale reference to atribute.characters
                    918: #
1.78      ht        919: # Revision 1.77  2000/09/28 15:54:50  ht
                    920: # schema error count includes all errors, not just those found at prep
                    921: # time
                    922: #
1.77      ht        923: # Revision 1.76  2000/09/28 15:09:14  ht
                    924: # try catching and returning any crashes
                    925: #
1.76      ht        926: # Revision 1.75  2000/09/28 08:41:57  ht
                    927: # add usage message
                    928: # add -o outfile cmd line arg
                    929: #
1.75      ht        930: # Revision 1.74  2000/09/27 13:48:47  richard
                    931: # Use infoset-like names for slots (now provided in XML.py) to reduce
                    932: # differences with infoset-based version.
                    933: #
1.74      richard   934: # Revision 1.73  2000/09/27 12:22:22  richard
                    935: # correct element.name to element.local in an error message
                    936: #
1.73      richard   937: # Revision 1.72  2000/09/26 14:29:36  richard
                    938: # Oops, didn't change AbInitio to XMLSchema.AbInitio when moving methods
                    939: #
1.72      richard   940: # Revision 1.71  2000/09/26 14:05:28  richard
                    941: # Move checkString methods from XMLSchema.py, because they may need to look
                    942: # at *instance* in-scope namespaces
                    943: #
1.71      richard   944: # Revision 1.70  2000/09/26 13:38:49  ht
                    945: # protect against undefined list itemType/union memberType
                    946: #
1.70      ht        947: # Revision 1.69  2000/09/23 11:17:31  ht
                    948: # merge in CR branch
                    949: #
1.69      ht        950: 
                    951: # Revision 1.68  2000/09/23 11:14:26  ht
                    952: # towards merge in CR branch
                    953: #
1.68      ht        954: # Revision 1.66.2.3  2000/09/21 09:14:33  ht
                    955: # property name change
                    956: #
                    957: # Revision 1.66.2.2  2000/09/11 12:23:27  ht
                    958: # Move to branch: more debug in vv crash
                    959: #
                    960: # Revision 1.68  2000/09/03 15:57:23  ht
                    961: # more debug in vv crash
                    962: 
                    963: # Revision 1.67  2000/09/11 12:59:09  ht
                    964: # allow stdin,
                    965: # fix stupid bug missing third schema on command line
                    966: 
                    967: # Revision 1.67  2000/08/31 11:48:41  ht
                    968: # Direct support for validating lists and unions
                    969: 
1.67      ht        970: # Revision 1.66  2000/08/22 13:11:30  ht
                    971: # handle type w/o qname as document validation type
                    972: # remove special treatment for AbInitio simple types on elements,
                    973: # thereby fixing list validation bug
1.69      ht        974: 
                    975: # Revision 1.66.2.3  2000/09/21 09:14:33  ht
                    976: # property name change
1.67      ht        977: #
1.69      ht        978: # Revision 1.66.2.2  2000/09/11 12:23:27  ht
                    979: # Move to branch: more debug in vv crash
                    980: #
                    981: # Revision 1.68  2000/09/03 15:57:23  ht
                    982: # more debug in vv crash
                    983: #
                    984: # Revision 1.67  2000/08/31 11:48:41  ht
                    985: # Direct support for validating lists and unions
                    986: #
                    987: 
1.66      ht        988: # Revision 1.66  2000/08/22 13:11:30  ht
                    989: # handle type w/o qname as document validation type
1.65      ht        990: # remove special treatment for AbInitio simple types on elements,
1.64      ht        991: # thereby fixing list validation bug
                    992: #
                    993: # Revision 1.65  2000/07/12 09:31:58  ht
1.63      ht        994: # try harder to always have a schema
                    995: #
                    996: # Revision 1.64  2000/07/10 14:39:02  ht
                    997: # prepare for fileinfo to runit
1.62      ht        998: #
                    999: # Revision 1.63  2000/07/05 09:05:37  ht
                   1000: # change name to PyLTXML
1.61      ht       1001: #
                   1002: # Revision 1.62  2000/07/03 09:37:38  ht
                   1003: # bail out if textonly has elt daughter(s)
1.60      ht       1004: # add missing import
                   1005: #
                   1006: # Revision 1.61  2000/06/27 09:25:51  ht
1.59      ht       1007: # attempt to handle interaction between xsi:type and <any>
                   1008: #
                   1009: # Revision 1.60  2000/06/24 11:17:07  ht
1.58      ht       1010: # fix bug in unqualified xsi:type
                   1011: #
                   1012: # Revision 1.59  2000/06/22 10:31:33  ht
                   1013: # Bug in unique processing -- broke on missing field
                   1014: #
                   1015: # Revision 1.58  2000/06/20 08:07:42  ht
                   1016: # merge xmlout branches back in to main line
                   1017: #
                   1018: 
                   1019: # Revision 1.57  2000/05/18 08:01:25  ht
                   1020: # fix bug in handling of xsi:type
                   1021: #
                   1022: # Revision 1.56  2000/05/14 12:19:34  ht
                   1023: # add context to checkSting calls
                   1024: #
                   1025: # Revision 1.55  2000/05/11 11:55:57  ht
                   1026: # just better handling of lax validation from other branch
                   1027: #
                   1028: # Revision 1.54.2.16  2000/06/15 16:03:20  ht
                   1029: # cover several missing definition cases
                   1030: #
                   1031: # Revision 1.54.2.15  2000/06/03 16:29:30  ht
                   1032: # oops, removing debugging comment
                   1033: #
                   1034: # Revision 1.54.2.14  2000/06/03 13:45:55  ht
                   1035: # catch arity bug in xsi:schemaLoc
                   1036: #
                   1037: # Revision 1.54.2.13  2000/05/30 09:35:43  ht
                   1038: # fix encoding bug when things break down altogether
                   1039: #
                   1040: # Revision 1.54.2.12  2000/05/29 08:46:53  ht
                   1041: # strong enforcement of nullable
                   1042: # add error codes to all errors
                   1043: # remove remaining __class__ tests
                   1044: # change error reporting wrt disallowed content
                   1045: #
                   1046: # Revision 1.54.2.11  2000/05/24 20:46:47  ht
                   1047: # make validateText a method, split across SimpleType and AbInitio
                   1048: #
                   1049: # Revision 1.54.2.10  2000/05/24 12:03:28  ht
                   1050: # modest effort to validate list types
                   1051: # fix bug in noNamespaceSchemaLocation handling at validation time
                   1052: #
                   1053: # Revision 1.54.2.9  2000/05/22 16:11:52  ht
                   1054: # use OpenStream, take more control of encoding
                   1055: #
                   1056: # Revision 1.54.2.8  2000/05/18 17:37:40  ht
                   1057: # parameterise stylesheet,
                   1058: # remove formatting from xsv:xsv attributes,
                   1059: # add namespace decl
                   1060: #
                   1061: # Revision 1.54.2.7  2000/05/18 07:59:48  ht
                   1062: # fix xsi:type validation bug
                   1063: #
                   1064: # Revision 1.54.2.6  2000/05/16 16:31:11  ht
                   1065: # fix bug handling un-typed element declarations == urType validation
                   1066: #
                   1067: # Revision 1.54.2.5  2000/05/14 12:29:59  ht
                   1068: # merge QName checking from main branch
                   1069: #
                   1070: # Revision 1.54.2.4  2000/05/12 15:15:01  ht
                   1071: # process keys even if type is simple,
                   1072: # add a few codes to get started
                   1073: #
                   1074: # Revision 1.54.2.3  2000/05/11 13:59:11  ht
                   1075: # convert verror/vwarn to produce elements
                   1076: # eliminate a few special error outputs in favour of special
                   1077: # sub-elements
1.57      ht       1078: #
                   1079: # Revision 1.54.2.2  2000/05/11 11:14:00  ht
                   1080: # more error protection
1.56      ht       1081: # handle lax recursively and at the start
                   1082: #
                   1083: # Revision 1.54.2.1  2000/05/10 11:36:47  ht
1.55      ht       1084: # begin converting to XML output
                   1085: #
                   1086: # Revision 1.56  2000/05/14 12:19:34  ht
1.54      ht       1087: # add context to checkSting calls
                   1088: #
                   1089: # Revision 1.55  2000/05/11 11:55:57  ht
                   1090: # just better handling of lax validation from other branch
1.53      ht       1091: #
                   1092: # Revision 1.54  2000/05/09 14:52:52  ht
                   1093: # Check for strings in a way that works with or without 16-bit support
1.52      richard  1094: #
                   1095: # Revision 1.53  2000/05/09 12:27:58  ht
                   1096: # replace our hack with python's url parsing stuff
1.51      ht       1097: # make f global for debugging
                   1098: #
                   1099: # Revision 1.52  2000/05/05 15:15:45  richard
1.50      richard  1100: # wrong (?) elt arg to verror in validateKeyRefs
                   1101: #
                   1102: # Revision 1.51  2000/05/04 07:56:35  ht
1.49      ht       1103: # Fix typo in opportunistic attribute validation
                   1104: #
                   1105: # Revision 1.50  2000/05/01 15:07:00  richard
1.48      richard  1106: # bug fix schema -> key.schema
                   1107: #
                   1108: # Revision 1.49  2000/05/01 10:05:43  ht
                   1109: # catch various missing file errors more gracefully
1.47      richard  1110: #
                   1111: # Revision 1.48  2000/04/28 15:40:01  richard
                   1112: # Implement xsi:null (still don't check nullable)
1.46      ht       1113: #
                   1114: # Revision 1.47  2000/04/28 15:11:23  richard
                   1115: # allow xsi: attributes on simple type
                   1116: # moved eltDecl code up validateElement ready for implementing xsi:null
1.45      ht       1117: #
                   1118: # Revision 1.46  2000/04/27 09:41:18  ht
                   1119: # remove raw types from error messages
1.44      ht       1120: #
                   1121: # Revision 1.45  2000/04/27 09:30:21  ht
                   1122: # check that inputs are actually schemas,
                   1123: # remove schema arg to doImport, checkInSchema
                   1124: #
                   1125: # Revision 1.44  2000/04/26 13:00:40  ht
1.43      ht       1126: # add copyright
                   1127: #
                   1128: # Revision 1.43  2000/04/24 20:46:40  ht
1.42      ht       1129: # cleanup residual bugs with massive rename,
                   1130: # rename Any to Wildcard,
                   1131: # replace AnyAttribute with Wildcard,
                   1132: # get validation of Wildcard working in both element and attribute contexts
1.41      ht       1133: #
                   1134: # Revision 1.42  2000/04/24 15:08:34  ht
                   1135: # minor glitches, tiny.xml works again
1.40      ht       1136: #
                   1137: # Revision 1.41  2000/04/24 15:00:09  ht
                   1138: # wholesale name changes -- init. caps for all classes,
1.39      ht       1139: # schema.py -> XMLSchema.py
                   1140: #
                   1141: # Revision 1.40  2000/04/24 11:09:17  ht
1.38      ht       1142: # make version string universally available
                   1143: #
                   1144: # Revision 1.39  2000/04/24 10:06:59  ht
1.37      ht       1145: # add version info to message
                   1146: #
                   1147: # Revision 1.38  2000/04/24 10:02:39  ht
                   1148: # change invocation message
1.36      ht       1149: #
                   1150: # Revision 1.37  2000/04/24 09:41:43  ht
                   1151: # clean up invocation some more, add k arg't to runit
1.35      ht       1152: #
                   1153: # Revision 1.36  2000/04/21 09:32:21  ht
                   1154: # another dose of resolveURL
1.34      ht       1155: # use tiny only if run from command line
                   1156: #
                   1157: # Revision 1.35  2000/04/20 22:12:43  ht
1.33      ht       1158: # use resolveURL on input, schemaLocs
                   1159: #
                   1160: # Revision 1.34  2000/04/20 15:45:08  ht
                   1161: # better handling of use of ns uri for loc
                   1162: #
                   1163: # Revision 1.33  2000/04/20 14:26:59  ht
                   1164: # merge in private and comp branches
                   1165: #
                   1166: # Revision 1.32.2.5  2000/04/20 14:25:54  ht
                   1167: # merge in comp branch
                   1168: #
                   1169: # Revision 1.32.2.4.2.9  2000/04/20 14:22:39  ht
                   1170: # manage document validation schema creation and search better
                   1171: #
                   1172: # Revision 1.32.2.4.2.8  2000/04/20 12:03:21  ht
                   1173: # Remove a few lingering effectiveTypes
                   1174: # Allow better for absent types etc.
                   1175: #
                   1176: # Revision 1.32.2.4.2.7  2000/04/14 21:18:27  ht
                   1177: # minor attr names/path changes to track schema
                   1178: #
                   1179: # Revision 1.32.2.4.2.6  2000/04/13 23:04:39  ht
                   1180: # allow for urType as simple type (?)
                   1181: # track Any->AnyWrap change
                   1182: #
                   1183: # Revision 1.32.2.4.2.5  2000/04/12 17:29:37  ht
                   1184: # begin work on model merger,
                   1185: #
                   1186: # Revision 1.32.2.4.2.4  2000/04/11 18:13:17  ht
                   1187: # interpolate attributeUse between complexType and attributeDeclaration,
                   1188: # parallel to particle
                   1189: #
                   1190: # Revision 1.32.2.4.2.3  2000/04/10 15:48:46  ht
                   1191: # put modest attribute validation in place
                   1192: #
                   1193: # Revision 1.32.2.4.2.2  2000/04/09 16:13:26  ht
                   1194: # working on complex type, attribute;
                   1195: # back out component.qname
                   1196: #
                   1197: # Revision 1.32.2.4.2.1  2000/04/05 12:12:36  ht
                   1198: # accommodate changes in schema.py
                   1199: #
                   1200: # Revision 1.32.2.4  2000/04/01 18:01:25  ht
                   1201: # various minor compatibility fixes
                   1202: #
                   1203: # Revision 1.32.2.3  2000/03/25 12:12:27  ht
                   1204: # restructure error handling/reporting;
                   1205: # allow for switching 208 on and off
                   1206: #
                   1207: # Revision 1.32.2.2  2000/03/21 15:57:23  ht
                   1208: # fix bug in skip,
1.32      ht       1209: # allow 208 override
                   1210: #
                   1211: # Revision 1.32.2.1  2000/03/20 17:22:52  ht
                   1212: # better coverage of <any>, including beginning of processcontents
                   1213: #
                   1214: # Revision 1.33  2000/03/20 17:20:53  ht
                   1215: # better coverage of <any>, including beginning of processcontents
                   1216: #
                   1217: # Revision 1.32  2000/03/08 15:28:46  ht
                   1218: # merge private branches back into public after 20000225 release
                   1219: #
                   1220: # Revision 1.31.2.3  2000/02/24 23:40:32  ht
                   1221: # fix any bug
                   1222: #
                   1223: # Revision 1.31.2.2  2000/02/21 09:18:13  ht
                   1224: # bug in <any> handling
                   1225: #
1.31      richard  1226: # Revision 1.31.2.1  2000/02/08 21:43:39  ht
                   1227: # fork private branch to track internal drafts
                   1228: # change calling sequence of checkinSchema
1.30      richard  1229: #
                   1230: # Revision 1.31.1.1  2000/02/08 13:54:25  ht
                   1231: # fork branch for non-public changes
1.29      ht       1232: # calling sequence to checkinSchema changed
                   1233: #
                   1234: # Revision 1.31  2000/01/13 16:55:42  richard
                   1235: # Finally do something with xsi:type
1.28      ht       1236: #
                   1237: # Revision 1.30  2000/01/10 17:36:34  richard
                   1238: # changes for xsi:schemaLocation
1.27      richard  1239: #
                   1240: # Revision 1.29  2000/01/08 23:33:50  ht
                   1241: # towards support for xsi:schemaLocation
1.26      ht       1242: #
                   1243: # Revision 1.28  2000/01/08 12:07:38  ht
                   1244: # Change command-line arg sequence in preparation for use of schemaLocation!!!!!
1.25      ht       1245: # Add debug printout for schemaLocation for now
                   1246: #
                   1247: # Revision 1.27  2000/01/07 17:08:26  richard
                   1248: # start on xsi:type
                   1249: #
1.24      ht       1250: # Revision 1.26  2000/01/06 14:59:38  ht
1.1       ht       1251: # fix command line bug, display args on entry
                   1252: #
                   1253: # Revision 1.25  2000/01/06 14:38:56  ht
                   1254: # detect cross-scope keyref and signal error
                   1255: #
                   1256: # Revision 1.24  2000/01/03 17:02:37  ht
                   1257: # Include result of sub-ordinate key checking in overall result
                   1258: # Accommodate new calling sequence for xpath.find
                   1259: # add Log and Id
                   1260: #
                   1261: #

Webmaster