Annotation of xmlschema/applyschema.py, revision 1.81

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

Webmaster