Annotation of xmlschema/applyschema.py, revision 1.54.2.1

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.54.2.1! ht          3: # $Id: applyschema.py,v 1.54 2000/05/09 14:52:52 ht Exp $
1.24      ht          4: 
1.2       ht          5: from PyXML import *
                      6: from XML import *
1.54.2.1! ht          7: import os
1.41      ht          8: import XMLSchema
1.28      ht          9: import layer
1.3       aqw        10: import sys
1.4       richard    11: import re
1.18      ht         12: import xpath
1.20      ht         13: import types
1.41      ht         14: import string
1.53      ht         15: from urlparse import urljoin
1.54.2.1! ht         16: import tempfile
1.4       richard    17: 
                     18: whitespace = re.compile("^[ \t\r\n]*$")
1.33      ht         19: xsi = "http://www.w3.org/1999/XMLSchema-instance"
1.54.2.1! ht         20: vsraw="$Revision: 1.54 $ of $Date: 2000/05/09 14:52:52 $"
1.40      ht         21: vss=string.split(vsraw)
1.41      ht         22: vs="XSV %s/%s of %s %s"%(string.split(XMLSchema.versionString)[0],
1.40      ht         23:                          vss[1],vss[5],vss[6])
1.5       richard    24: 
1.2       ht         25: def readXML(url):
1.14      ht         26:   input = Open(url, NSL_read|NSL_read_namespaces|NSL_read_defaulted_attributes)
1.5       richard    27: #  item = GetNextQueryItem(input, ParseQuery(input.doctype, "."))
                     28: #  elem = Element(item, input.doctype)
                     29:   elem = Element(input, 1)
1.54.2.1! ht         30:   encoding = input.doctype.encoding
        !            31:   if encoding=='unknown':
        !            32:     encoding=None
1.2       ht         33:   Close(input)
1.54.2.1! ht         34:   return (elem,encoding)                           # error return??
1.2       ht         35: 
1.20      ht         36: def validate(element, typedef, schema):
1.33      ht         37:   schema.factory.errors=0
                     38:   validateElement(element, typedef, schema)
                     39:   return schema.factory.errors
1.2       ht         40: 
1.21      ht         41: def validateElement(element, type, schema,eltDecl=None):
1.4       richard    42:   global vel, vtype
                     43:   vel = element
                     44:   vtype = type
1.2       ht         45: #  print "validating element %s against %s" % (element.name, type)
1.47      richard    46:   if not eltDecl:
                     47:     eqn=XMLSchema.QName(None,element.local,element.uri)
                     48:     if s.vElementTable.has_key(eqn):
                     49:       eltDecl=s.vElementTable[eqn]
                     50: #  nullable = eltDecl and eltDecl.nullable
1.48      richard    51:   nullable = 1
                     52:   nulled = 0
                     53:   if element.nsattrs.has_key((xsi, "null")):
                     54:     if not nullable:
                     55:       verror(element, "xsi:null specified on non-nullable element %s" % element.name)
                     56:       return
                     57:     nulled = (element.nsattrs[(xsi, "null")].value == "true")
1.31      richard    58:   if element.nsattrs.has_key((xsi, "type")):
                     59:     t = element.nsattrs[(xsi, "type")].value;
                     60:     try:
1.41      ht         61:       qt = XMLSchema.QName(t, element.nsdict)
1.31      richard    62:     except SchemaError:
1.33      ht         63:       verror(element,"namespace not found for xsi:type %s" % t,schema)
                     64:       return
1.31      richard    65:     if schema.vComplexTypeTable.has_key(qt):
                     66:       xsitype=schema.vComplexTypeTable[qt]
                     67:     elif schema.vSimpleTypeTable.has_key(qt):
                     68:       xsitype=schema.vSimpleTypeTable[qt]
                     69:     else:
1.33      ht         70:       verror(element,"xsi:type %s undefined" % qt,schema)
                     71:       return
1.31      richard    72:     if not xsitype.isSubtype(type):
1.33      ht         73:       verror(element,"xsi:type %s is not a subtype of the declared type %s" % (qt, type.name),schema)
                     74:       return
                     75:     vwarn(element,"using xsi:type %s instead of original %s" % (qt, type.name))
                     76:     type = xsitype
1.48      richard    77:   if nulled:
                     78:     return validateElementNull(element, type, schema)
                     79:   elif type:
1.33      ht         80:     # might have none in case of recursive call inside <any/>
1.41      ht         81:     if isinstance(type, XMLSchema.AbInitio):
1.33      ht         82:       return validateElementSimple(element, type, schema)
1.41      ht         83:     if isinstance(type, XMLSchema.SimpleType):
1.33      ht         84:       return validateElementSimple(element, type.primitiveType, schema)
                     85:     assignAttributeTypes(element, type.attributeDeclarations,
                     86:                               type.prohibitedSubstitutions, schema)
                     87:     validateAttributeTypes(element, element.attrTable,
                     88:                            type.attributeDeclarations, schema)
                     89:   #  print "assigning types for %s" % element.name
                     90:     assignChildTypes(element.children, type.elementTable,
                     91:                           type.prohibitedSubstitutions, schema)
                     92:     # we must look at the content model before checking the types, so that
                     93:     # we know which children matched <any>
                     94:     validateContentModel(element, type, schema)
                     95:   validateChildTypes(element.children, schema)
1.21      ht         96:   if eltDecl:
1.33      ht         97:     validateKeys(eltDecl,element)
1.2       ht         98: 
1.48      richard    99: def validateElementNull(element, type, schema):
                    100:   if len(element.children) != 0:
                    101:     verror(element,"element %s is nulled but is not empty" % element.name,schema)
                    102:   # XXX should check for fixed value constraint
                    103: 
1.2       ht        104: def validateElementSimple(element, type, schema):
                    105:   # check that:
1.47      richard   106:   #   it has no attributes (except xsi: ones)
1.2       ht        107:   #   it has one pcdata child, and if so
                    108:   #     the text of the pcdata matches the type
                    109:   if element.attrs:
1.47      richard   110:     for a in element.attrs.values():
                    111:       if a.uri != xsi:
                    112:         verror(element,"element {%s}%s with simple type not allowed attributes" % (element.uri, element.name),schema)
                    113:         return
1.2       ht        114:   return validateTextModel(element, type, schema)
                    115: 
                    116: def validateText(text, type, schema):
1.41      ht        117:   if isinstance(type,XMLSchema.SimpleType):
                    118:     if type==XMLSchema.urType:
1.33      ht        119:       return
                    120:     else:
                    121:       return type.primitiveType.checkString(text)
                    122:   else:
                    123:     return type.checkString(text)
1.2       ht        124: 
1.9       ht        125: def assignAttributeTypes(element, attrdefs, extendable, schema):
1.2       ht        126:   # look up each attribute in attrdefs and assign its type
                    127:   # error if attr declaration is not found and type is not extendable
1.15      richard   128: #  print "assigning attrs for %s {%s}%s" % (element.name, element.uri, element.local)
1.33      ht        129:   element.attrTable={}
1.9       ht        130:   for a in element.attrs.values():
1.15      richard   131: #    print "assigning attr %s {%s}%s" % (a.name, a.uri, a.local)
1.41      ht        132:     an=XMLSchema.QName(None,a.local,a.uri)
1.33      ht        133:     element.attrTable[an]=a
1.27      richard   134:     if a.uri == xsi:
1.43      ht        135:       if a.local not in ('type','null','schemaLocation','noNamespaceSchemaLocation'):
1.33      ht        136:         verror(element,"unknown xsi attribute %s" % an,schema)
1.27      richard   137:     elif attrdefs.has_key(an):
1.43      ht        138:       a.type = attrdefs[an].attributeDeclaration
                    139:     elif (attrdefs.has_key("#any") and
                    140:           attrdefs["#any"].attributeDeclaration.allows(a.uri)):
                    141:       a.type = attrdefs["#any"].attributeDeclaration
1.2       ht        142:     else:
1.33      ht        143:       verror(element,"undeclared attribute %s" % an,schema)
1.2       ht        144:       a.type = None
1.33      ht        145:   return
1.2       ht        146: 
1.33      ht        147: def validateAttributeTypes(element,attrs, attrdefs, schema):
1.2       ht        148:   # check that each attribute matches its type
                    149:   # check that all required attributes are present
                    150:   # add defaulted attributes (shouldn't need to check their types)
1.33      ht        151:   for (adq,ad) in attrdefs.items():
                    152:     if ad.minOccurs==1 and not attrs.has_key(adq):
                    153:       verror(element,"required attribute %s not present"%adq,schema)
                    154:   for (an,a) in attrs.items():
                    155:     if an.uri!=xsi and a.type:
1.43      ht        156:       if isinstance(a.type,XMLSchema.Wildcard):
                    157:         res=a.type.validate(a,schema,'attribute',element)
                    158:       else:
                    159:         res=validateText(a.value,a.type.typeDefinition,
                    160:                          schema)
1.33      ht        161:       if res:
                    162:         verror(element,"attribute type check failed for %s: %s%s"%(an,
                    163:                                                                    a.value,
                    164:                                                                    res),
                    165:                schema)
1.2       ht        166: 
                    167: def assignChildTypes(children, elementTable, extendable, schema):
                    168:   # look up each child tag and record the type
                    169:   # (it may not be an error if it is not declared; we don't know that
                    170:   #  until we see what it matches in the content model)
                    171:   for child in children:
                    172:     if child.__class__ == Element:
1.41      ht        173:       qname = XMLSchema.QName(None,child.local,child.uri)
1.10      richard   174:       if elementTable.has_key(qname):
                    175:        child.type = elementTable[qname][1]
1.2       ht        176:       else:
                    177:        child.type = None
                    178:   return 1
                    179: 
                    180: def validateContentModel(element, type, schema):
                    181:   # trace a path through the content model
                    182:   # if a child matches an <any tag=... type=...> we need to indicate
                    183:   # that that child should be validated with its xsd:type if it has one
                    184:   # if a child matches some other kind of <any> we need to indicate
                    185:   # that it's not an error if we can't find its type
                    186: 
1.4       richard   187: #  print "validating model for %s content %s" % (element.name, type.content)
1.33      ht        188:   if type.contentType == "empty":
                    189:     validateEmptyModel(element, type, schema)
                    190:   elif type.contentType == "textOnly":
                    191:     validateTextModel(element, type.model, schema)
                    192:   else:
                    193:     validateElementModel(element, type.fsm,
                    194:                          type.contentType == "mixed", schema)
1.2       ht        195: 
                    196: def validateEmptyModel(element, type, schema):
                    197:   if len(element.children) != 0:
1.33      ht        198:     verror(element,"element %s must be empty but is not" % element.name,schema)
1.2       ht        199: 
                    200: def validateTextModel(element, type, schema):
                    201:   # check that:
                    202:   #   it has one pcdata child, and if so
                    203:   #     the text of the pcdata matches the type
                    204:   name = element.name
                    205:   n = len(element.children)
                    206:   if n > 1:
1.46      ht        207:     verror(element,"element {%s}%s with simple type not allowed %s (> 1) children" % (element.uri, name, n),schema)
1.33      ht        208:     return
1.2       ht        209:   elif n > 0 and element.children[0].__class__ != Pcdata:
1.46      ht        210:     verror(element,"element {%s}%s with simple type not allowed non-text children" % (element.uri,name),schema)
1.33      ht        211:     return
1.2       ht        212:   else:
                    213:     if n == 0:
                    214:       text = ""
                    215:     else:
                    216:       text = element.children[0].value
1.33      ht        217:     res=validateText(text, type, schema)
                    218:     if res:
                    219:       verror(element,"element content failed type check: %s%s"%(text,res),
                    220:              schema)
1.2       ht        221: 
1.4       richard   222: def validateElementModel(element, fsm, mixed, schema):
1.33      ht        223:   #  print "validating element model for %s" % element.name
1.4       richard   224:   n = fsm.startNode
                    225:   for c in element.children:
                    226:     if c.__class__ == Pcdata:
1.19      ht        227:       if (not mixed) and (not whitespace.match(c.value)):
1.33      ht        228:        verror(c,"text not allowed in element %s: |%s|" % (element.name,c.value),schema)
                    229:        return
1.4       richard   230:     elif c.__class__ == Element:
1.41      ht        231:       qname = XMLSchema.QName(None, c.local, c.uri)
1.8       richard   232:       next = None
1.13      richard   233:       anynext = None
1.4       richard   234:       for e in n.edges:
1.10      richard   235:         if e.label == qname:
1.8       richard   236:          next = e.dest
1.4       richard   237:          break
1.43      ht        238:         if isinstance(e.label, XMLSchema.Wildcard):
1.41      ht        239:           if e.label.allows(c.uri):
                    240:             anynext = e.dest
                    241:             anylab = e.label
1.8       richard   242:       if not next:
1.13      richard   243:         if anynext:
                    244:           n = anynext
1.17      richard   245: # this is no longer an error, but something more complicated is XXX
                    246: #          if c.type:
                    247: #            where(child.where)
                    248: #            print "element matched <any> but had a type assigned"
                    249: #            v = 0
                    250: #          else:
                    251: #            c.type = "<any>"
1.33      ht        252:           c.type = anylab
1.13      richard   253:         else:
1.41      ht        254:           verror(c,"element %s not allowed here in element %s" % (qname, XMLSchema.QName(None,element.local,element.uri)),schema)
1.33      ht        255:           fsm.printme(sys.stderr)
1.13      richard   256:       else:
                    257:         n = next
1.4       richard   258:   if not n.isEndNode:
1.33      ht        259:     verror(element,"content of %s is not allowed to end here" % element.name,
                    260:            schema,1)
                    261:     fsm.printme(sys.stderr)
                    262:   return
1.2       ht        263: 
                    264: def validateChildTypes(children, schema):
                    265:   # validate each child element against its type, if we know it
                    266:   # report an error if we don't know it and it's not in <any>
1.7       richard   267:   v = 1
1.2       ht        268:   for child in children:
                    269:     if child.__class__ == Element:
1.33      ht        270:       if child.type:
1.43      ht        271:         child.type.validate(child,schema,'element',child)
1.2       ht        272:       else:
1.33      ht        273:        verror(child,
1.41      ht        274:                "undeclared element %s" % XMLSchema.QName(None,child.local,child.uri),
1.33      ht        275:                schema)
1.2       ht        276: 
1.21      ht        277: def validateKeys(decl,elt):
1.22      ht        278:   elt.keyTabs={}
1.33      ht        279:   validateKeys1(elt,decl.keys,1)
                    280:   validateKeys1(elt,decl.uniques,0)
                    281:   validateKeyRefs(elt,decl.keyrefs)
1.22      ht        282: 
                    283: def validateKeys1(elt,kds,reqd):
                    284:   for key in kds:
1.21      ht        285:     tab={}
                    286:     sp=xpath.XPath(key.selector)
1.24      ht        287:     candidates=sp.find(elt)
1.21      ht        288:     if candidates:
                    289:       fps=map(lambda f:xpath.XPath(f),key.field)
                    290:       for s in candidates:
1.22      ht        291:         keyKey=buildKey(s,fps)
                    292:         if reqd and not keyKey:
1.33      ht        293:           verror(s,
                    294:                  "missing one or more fields %s from key %s"%(key.field,
                    295:                                                               key.name),
1.50      richard   296:                  key.schema)
1.22      ht        297:           break
1.21      ht        298:        if len(keyKey)>1:
                    299:          keyKey=tuple(keyKey)
                    300:        else:
                    301:          keyKey=keyKey[0]
                    302:        if tab.has_key(keyKey):
1.33      ht        303:          verror(s,"duplicate key %s, first appearance was"%str(keyKey),
                    304:                  key.schema)
1.43      ht        305:          XMLSchema.where(tab[keyKey].where)
1.21      ht        306:        else:
                    307:          tab[keyKey]=s
1.22      ht        308:     elt.keyTabs[key.name]=tab
                    309: 
                    310: def buildKey(s,fps):
                    311:   keyKey=[]
                    312:   for fp in fps:
1.24      ht        313:     kv=fp.find(s)
1.22      ht        314:     if kv:
                    315:       if len(kv)>1:
1.33      ht        316:         vwarn(s,"oops, multiple field hits for %s at %s: %s"%(fp.str,s,kv))
1.22      ht        317:       if isinstance(kv[0],Element):
                    318:         if (len(kv[0].children)>0 and
                    319:             isinstance(kv[0].children[0],Pcdata)):
                    320:           keyKey.append(kv[0].children[0].value)
                    321:         else:
                    322:           # XPath says in this case value is the empty string
                    323:           pass
1.54      ht        324:       elif somestring(type(kv[0])):
1.22      ht        325:         keyKey.append(kv[0])
                    326:       else:
1.33      ht        327:         vwarn(s,"oops, key value %s:%s"%(type(kv[0]),kv[0]))
1.22      ht        328:     else:
                    329:       return None
                    330:   return keyKey
                    331: 
                    332: def validateKeyRefs(elt,krds):
                    333:   res=1
                    334:   for ref in krds:
1.25      ht        335:     if elt.keyTabs.has_key(ref.refer):
                    336:       keyTab=elt.keyTabs[ref.refer]
                    337:       if keyTab=='bogus':
                    338:        break
                    339:     else:
                    340:       elt.keyTabs[ref.refer]='bogus'
1.52      richard   341:       verror(elt,
1.33      ht        342:              "No key or unique constraint named %s declared, refed by keyref %s"%(ref.refer,ref.name),
                    343:              ref.schema)
1.25      ht        344:       break
1.22      ht        345:     sp=xpath.XPath(ref.selector)
1.24      ht        346:     candidates=sp.find(elt)
1.22      ht        347:     if candidates:
                    348:       fps=map(lambda f:xpath.XPath(f),ref.field)
                    349:       for s in candidates:
                    350:         keyKey=buildKey(s,fps)
                    351:         if not keyKey:
                    352:           break
                    353:        if len(keyKey)>1:
                    354:          keyKey=tuple(keyKey)
                    355:        else:
                    356:          keyKey=keyKey[0]
1.25      ht        357:        if not keyTab.has_key(keyKey):
1.33      ht        358:          verror(s,"no key in %s for %s"%(ref.refer,str(keyKey)),ref.schema)
1.21      ht        359: 
1.30      richard   360: def findSchemaLocs(element):
                    361:   pairs = []
                    362:   for a in element.attrs.values():
1.43      ht        363:     if a.uri == xsi:
                    364:       if a.local == "schemaLocation":
                    365:         scls=string.split(a.value)
                    366:         while scls:
                    367:           pairs.append((scls[0], scls[1]))
                    368:           scls=scls[2:]
                    369:       elif a.local == "noNamespaceSchemaLocation":
                    370:         pairs.append(None,a.value)
1.30      richard   371:   for c in element.children:
                    372:     if isinstance(c, Element):
1.43      ht        373:       scl=findSchemaLocs(c)
                    374:       if scl:
                    375:         pairs = pairs + scl
1.30      richard   376:   return pairs
                    377:   
1.54.2.1! ht        378: def runitAndShow(en,rns=[],k=0):
        !           379:   res=runit(en,rns,k)
        !           380:   errout=openErrOut()
        !           381:   res.printme(errout)
        !           382:   sys.stderr.write("\n")
        !           383:   Close(errout)
        !           384:   return res
        !           385: 
1.37      ht        386: def runit(en,rns=[],k=0):
1.54.2.1! ht        387:   global s,e,t,f,res
1.33      ht        388: 
1.45      ht        389:   ss = s = None
1.33      ht        390: 
1.54.2.1! ht        391:   res=Element("xsv")
        !           392:   res.addAttr("version",vs)
        !           393:   res.addAttr("target",en)
1.38      ht        394:   if rns:
1.54.2.1! ht        395:     res.addAttr("schemas",string.join(rns,' '))
        !           396: 
        !           397:   rdn=tempfile.mktemp("xsverrs")
        !           398:   redirect=open(rdn,"w+")
        !           399:   os.dup2(2,10)                        # save stderr
        !           400:   os.dup2(redirect.fileno(),2)
        !           401:   try:
        !           402:     (e,encoding)=readXML(en)
        !           403:   except XMLinter.error:
        !           404:     res.addAttr('outcome',"validation not attempted")
        !           405:     registerRawErrors(redirect,res)
        !           406:     # how do I get stderr back!!!
        !           407:     os.dup2(10,2)
        !           408:     return res
        !           409:   registerRawErrors(redirect,res)
        !           410:   os.dup2(10,2)
1.30      richard   411: 
1.41      ht        412:   f=XMLSchema.newFactory()
1.36      ht        413:   base=f.fileNames[0]
1.53      ht        414:   ren=urljoin(base,en)
1.30      richard   415: 
1.28      ht        416:   if rns:
1.49      ht        417:     try:
1.53      ht        418:       s = XMLSchema.fromFile(urljoin(base,rns[0]),f)
1.49      ht        419:     except XMLinter.error:
                    420:       pass
1.30      richard   421:     for rn in rns[1:]:
1.49      ht        422:       try:
1.53      ht        423:         ss=ss or XMLSchema.fromFile(urljoin(base,rn),f)
1.49      ht        424:       except XMLinter.error:
                    425:         pass
1.33      ht        426:   else:
1.43      ht        427:     s = XMLSchema.Schema(f,None)
1.33      ht        428:     s.targetNS='##dummy'
1.30      richard   429: 
1.45      ht        430:   if not s:
                    431:     s=ss
                    432: 
1.30      richard   433:   schemaLocs = findSchemaLocs(e)
1.33      ht        434:   sys.stderr.write("schemaLocations from instance: %s\n" % schemaLocs)
1.30      richard   435:   for (ns, sl) in schemaLocs:
1.49      ht        436:     try:
                    437:       XMLSchema.checkinSchema(f, ns, sl,e,ren)
                    438:     except XMLinter.error:
                    439:       pass
1.30      richard   440:   
1.34      ht        441:   if (e.uri and
                    442:       (e.uri not in ('http://www.w3.org/XML/1998/namespace',
                    443:                    'http://www.w3.org/1999/XMLSchema-instance')) and
                    444:       not f.schemas.has_key(e.uri)):
                    445:     try:
                    446:       sys.stderr.write("no schema yet for %s, trying namespace URI itself. . ."%
                    447:                        e.uri)
1.49      ht        448:       XMLSchema.checkinSchema(f,e.uri,e.uri,e,ren)
1.34      ht        449:     except XMLinter.error:
1.49      ht        450:       sys.stderr.write("Resolution of namespace URI %s failed.\n"%e.uri)
1.30      richard   451:     
1.41      ht        452:   ecount=XMLSchema.prepare(f)
1.33      ht        453:   
                    454:   if ecount:
                    455:     if k:
                    456:       km="continuing"
                    457:     else:
                    458:       km="stopping without validating instance"
                    459:     em="%d errors in schemas, %s"%(ecount,km)
                    460:     if not k:
                    461:       sys.stderr.write("%s\n"%em)
1.54.2.1! ht        462:       return res
1.33      ht        463:   else:
                    464:     em="Schema(s) OK"
                    465:   sys.stderr.write("%s\n"%em)
1.30      richard   466: 
1.28      ht        467:   cl=string.find(':',e.name)
                    468:   if cl>-1:
                    469:     prefix=e.name[0:cl]
                    470:   else:
                    471:     prefix=''
1.41      ht        472:   eltname = XMLSchema.QName(prefix,e.local,e.uri)
1.30      richard   473: 
                    474:   if not s:
                    475:     # any one will do
1.33      ht        476:     s = f.sfors
                    477:   t=None
                    478:   
                    479:   if s and s.vElementTable.has_key(eltname):
                    480:     t=s.vElementTable[eltname].typeDefinition
                    481:   if not t:
                    482:     sys.stderr.write("can't validate, because can't find type for %s\n" % eltname)
1.54.2.1! ht        483:     return res
1.33      ht        484: 
                    485:   if e and s:
                    486:     if t.name:
                    487:       sys.stderr.write("validating with type %s\n" % t.name)
                    488:     else:
                    489:       sys.stderr.write("validating with anonymous type\n")
                    490:     validate(e, t, s)
                    491:     if s.factory.errors:
                    492:       sys.stderr.write("%d validation errors\n" % s.factory.errors)
                    493:     else:
                    494:       sys.stderr.write("No errors\n")
1.54.2.1! ht        495:     return res
        !           496: 
        !           497: def registerRawErrors(redirect,res):
        !           498:   if redirect.tell(): 
        !           499:     redirect.seek(0)
        !           500:     ro=Element("rawError")
        !           501:     o="\n%s"%redirect.read()
        !           502:     ro.children=[Pcdata(o)]
        !           503:     res.children=[ro]
        !           504:   redirect.close()
        !           505: 
        !           506: def openErrOut(encoding=None):
        !           507:   file=FOpen(sys.stderr,NSL_write+NSL_write_plain)
        !           508:   if encoding:
        !           509:     es=" encoding='%s'"%encoding
        !           510:   else:
        !           511:     es=""
        !           512:   sys.stderr.write("<?xml version='1.0'%s?>\n"%es)
        !           513:   sys.stderr.write("<?xml-stylesheet type='text/xsl' href='xsv.xsl'?>\n")
        !           514:   return file
1.30      richard   515: 
1.33      ht        516: def verror(elt,message,schema,two=0):
                    517:   sys.stderr.write("Validation error: ")
                    518:   if two:
1.41      ht        519:     XMLSchema.where(elt.where2)
1.33      ht        520:   else:
1.41      ht        521:     XMLSchema.where(elt.where)
1.33      ht        522:   sys.stderr.write(" ")
                    523:   sys.stderr.write(message)
                    524:   sys.stderr.write("\n")
                    525:   schema.factory.errors=schema.factory.errors+1
                    526: 
                    527: def vwarn(elt,message):
                    528:   sys.stderr.write("Validation warning: ")
                    529:   if elt:
1.43      ht        530:     XMLSchema.where(elt.where)
1.33      ht        531:   sys.stderr.write(message)
                    532:   sys.stderr.write("\n")
                    533: 
1.24      ht        534: 
1.54.2.1! ht        535: # add a method to Element
        !           536: 
        !           537: def addAttr(self,name,value):
        !           538:   self.attrs[name]=Attribute(name,value)
        !           539: 
        !           540: Element.addAttr=addAttr
        !           541: 
1.41      ht        542: # validation methods for schema components
                    543: 
1.43      ht        544: def av(self,child,schema,kind,elt):
1.41      ht        545:   q = XMLSchema.QName(None,child.local,child.uri)
1.43      ht        546:   vwarn(elt,"allowing %s because it matched wildcard(%s)" %
                    547:         (q,self.allowed))
                    548:   if self.processContents!='skip':
1.41      ht        549:     if schema.factory.schemas.has_key(child.uri):
                    550:       # only try if we might win -- needs work
                    551:       try:
1.43      ht        552:         if kind=='element':
                    553:           e = schema.vElementTable[q]
                    554:         else:
                    555:           e = schema.vAttributeTable[q]
1.41      ht        556:       except KeyError:
                    557:         e=None
                    558:       if e:
1.43      ht        559:         vwarn(None,"validating it against %s" %
                    560:               (e.typeDefinition.name or 'anonymous type'))
                    561:         if kind=='element':
                    562:           validateElement(child, e.typeDefinition, schema)
                    563:         else:
1.51      ht        564:           return validateText(child.value,e.typeDefinition,schema)
1.43      ht        565:       elif self.processContents=='strict':
                    566:         verror(elt,
                    567:                "can't find a type for wildcard-matching %s %s" %(kind, q),
                    568:                schema)
                    569: 
                    570: XMLSchema.Wildcard.validate=av
1.42      ht        571: 
1.43      ht        572: def tv(self,child,schema,kind,elt):
1.42      ht        573:   validateElement(child, self, schema)
1.41      ht        574: 
1.43      ht        575: XMLSchema.Type.validate=XMLSchema.AbInitio.validate=tv
1.41      ht        576: 
1.42      ht        577: # run at import if top
                    578: 
                    579: if __name__=='__main__':
                    580:   argl=sys.argv[1:]
                    581:   k=0
                    582:   while argl:
                    583:     if argl[0]=='-k':
                    584:       k=1
                    585:     else:
                    586:       break
                    587:     argl=argl[1:]
                    588: 
                    589:   if argl:
1.54.2.1! ht        590:     runitAndShow(argl[0],argl[1:],k)
1.42      ht        591:   else:
1.54.2.1! ht        592:     runitAndShow("tiny.xml",["tiny.xsd"],k)
1.41      ht        593: 
1.25      ht        594: # $Log: applyschema.py,v $
1.54.2.1! ht        595: # Revision 1.54  2000/05/09 14:52:52  ht
        !           596: # Check for strings in a way that works with or without 16-bit support
        !           597: #
1.54      ht        598: # add context to checkSting calls
                    599: #
                    600: # Revision 1.55  2000/05/11 11:55:57  ht
                    601: # just better handling of lax validation from other branch
1.53      ht        602: #
                    603: # Revision 1.54  2000/05/09 14:52:52  ht
                    604: # Check for strings in a way that works with or without 16-bit support
1.52      richard   605: #
                    606: # Revision 1.53  2000/05/09 12:27:58  ht
                    607: # replace our hack with python's url parsing stuff
1.51      ht        608: # make f global for debugging
                    609: #
                    610: # Revision 1.52  2000/05/05 15:15:45  richard
1.50      richard   611: # wrong (?) elt arg to verror in validateKeyRefs
                    612: #
                    613: # Revision 1.51  2000/05/04 07:56:35  ht
1.49      ht        614: # Fix typo in opportunistic attribute validation
                    615: #
                    616: # Revision 1.50  2000/05/01 15:07:00  richard
1.48      richard   617: # bug fix schema -> key.schema
                    618: #
                    619: # Revision 1.49  2000/05/01 10:05:43  ht
                    620: # catch various missing file errors more gracefully
1.47      richard   621: #
                    622: # Revision 1.48  2000/04/28 15:40:01  richard
                    623: # Implement xsi:null (still don't check nullable)
1.46      ht        624: #
                    625: # Revision 1.47  2000/04/28 15:11:23  richard
                    626: # allow xsi: attributes on simple type
                    627: # moved eltDecl code up validateElement ready for implementing xsi:null
1.45      ht        628: #
                    629: # Revision 1.46  2000/04/27 09:41:18  ht
                    630: # remove raw types from error messages
1.44      ht        631: #
                    632: # Revision 1.45  2000/04/27 09:30:21  ht
                    633: # check that inputs are actually schemas,
                    634: # remove schema arg to doImport, checkInSchema
                    635: #
                    636: # Revision 1.44  2000/04/26 13:00:40  ht
1.43      ht        637: # add copyright
                    638: #
                    639: # Revision 1.43  2000/04/24 20:46:40  ht
1.42      ht        640: # cleanup residual bugs with massive rename,
                    641: # rename Any to Wildcard,
                    642: # replace AnyAttribute with Wildcard,
                    643: # get validation of Wildcard working in both element and attribute contexts
1.41      ht        644: #
                    645: # Revision 1.42  2000/04/24 15:08:34  ht
                    646: # minor glitches, tiny.xml works again
1.40      ht        647: #
                    648: # Revision 1.41  2000/04/24 15:00:09  ht
                    649: # wholesale name changes -- init. caps for all classes,
1.39      ht        650: # schema.py -> XMLSchema.py
                    651: #
                    652: # Revision 1.40  2000/04/24 11:09:17  ht
1.38      ht        653: # make version string universally available
                    654: #
                    655: # Revision 1.39  2000/04/24 10:06:59  ht
1.37      ht        656: # add version info to message
                    657: #
                    658: # Revision 1.38  2000/04/24 10:02:39  ht
                    659: # change invocation message
1.36      ht        660: #
                    661: # Revision 1.37  2000/04/24 09:41:43  ht
                    662: # clean up invocation some more, add k arg't to runit
1.35      ht        663: #
                    664: # Revision 1.36  2000/04/21 09:32:21  ht
                    665: # another dose of resolveURL
1.34      ht        666: # use tiny only if run from command line
                    667: #
                    668: # Revision 1.35  2000/04/20 22:12:43  ht
1.33      ht        669: # use resolveURL on input, schemaLocs
                    670: #
                    671: # Revision 1.34  2000/04/20 15:45:08  ht
                    672: # better handling of use of ns uri for loc
                    673: #
                    674: # Revision 1.33  2000/04/20 14:26:59  ht
                    675: # merge in private and comp branches
                    676: #
                    677: # Revision 1.32.2.5  2000/04/20 14:25:54  ht
                    678: # merge in comp branch
                    679: #
                    680: # Revision 1.32.2.4.2.9  2000/04/20 14:22:39  ht
                    681: # manage document validation schema creation and search better
                    682: #
                    683: # Revision 1.32.2.4.2.8  2000/04/20 12:03:21  ht
                    684: # Remove a few lingering effectiveTypes
                    685: # Allow better for absent types etc.
                    686: #
                    687: # Revision 1.32.2.4.2.7  2000/04/14 21:18:27  ht
                    688: # minor attr names/path changes to track schema
                    689: #
                    690: # Revision 1.32.2.4.2.6  2000/04/13 23:04:39  ht
                    691: # allow for urType as simple type (?)
                    692: # track Any->AnyWrap change
                    693: #
                    694: # Revision 1.32.2.4.2.5  2000/04/12 17:29:37  ht
                    695: # begin work on model merger,
                    696: #
                    697: # Revision 1.32.2.4.2.4  2000/04/11 18:13:17  ht
                    698: # interpolate attributeUse between complexType and attributeDeclaration,
                    699: # parallel to particle
                    700: #
                    701: # Revision 1.32.2.4.2.3  2000/04/10 15:48:46  ht
                    702: # put modest attribute validation in place
                    703: #
                    704: # Revision 1.32.2.4.2.2  2000/04/09 16:13:26  ht
                    705: # working on complex type, attribute;
                    706: # back out component.qname
                    707: #
                    708: # Revision 1.32.2.4.2.1  2000/04/05 12:12:36  ht
                    709: # accommodate changes in schema.py
                    710: #
                    711: # Revision 1.32.2.4  2000/04/01 18:01:25  ht
                    712: # various minor compatibility fixes
                    713: #
                    714: # Revision 1.32.2.3  2000/03/25 12:12:27  ht
                    715: # restructure error handling/reporting;
                    716: # allow for switching 208 on and off
                    717: #
                    718: # Revision 1.32.2.2  2000/03/21 15:57:23  ht
                    719: # fix bug in skip,
1.32      ht        720: # allow 208 override
                    721: #
                    722: # Revision 1.32.2.1  2000/03/20 17:22:52  ht
                    723: # better coverage of <any>, including beginning of processcontents
                    724: #
                    725: # Revision 1.33  2000/03/20 17:20:53  ht
                    726: # better coverage of <any>, including beginning of processcontents
                    727: #
                    728: # Revision 1.32  2000/03/08 15:28:46  ht
                    729: # merge private branches back into public after 20000225 release
                    730: #
                    731: # Revision 1.31.2.3  2000/02/24 23:40:32  ht
                    732: # fix any bug
                    733: #
                    734: # Revision 1.31.2.2  2000/02/21 09:18:13  ht
                    735: # bug in <any> handling
                    736: #
1.31      richard   737: # Revision 1.31.2.1  2000/02/08 21:43:39  ht
                    738: # fork private branch to track internal drafts
                    739: # change calling sequence of checkinSchema
1.30      richard   740: #
                    741: # Revision 1.31.1.1  2000/02/08 13:54:25  ht
                    742: # fork branch for non-public changes
1.29      ht        743: # calling sequence to checkinSchema changed
                    744: #
                    745: # Revision 1.31  2000/01/13 16:55:42  richard
                    746: # Finally do something with xsi:type
1.28      ht        747: #
                    748: # Revision 1.30  2000/01/10 17:36:34  richard
                    749: # changes for xsi:schemaLocation
1.27      richard   750: #
                    751: # Revision 1.29  2000/01/08 23:33:50  ht
                    752: # towards support for xsi:schemaLocation
1.26      ht        753: #
                    754: # Revision 1.28  2000/01/08 12:07:38  ht
                    755: # Change command-line arg sequence in preparation for use of schemaLocation!!!!!
1.25      ht        756: # Add debug printout for schemaLocation for now
                    757: #
                    758: # Revision 1.27  2000/01/07 17:08:26  richard
                    759: # start on xsi:type
                    760: #
1.24      ht        761: # Revision 1.26  2000/01/06 14:59:38  ht
1.1       ht        762: # fix command line bug, display args on entry
                    763: #
                    764: # Revision 1.25  2000/01/06 14:38:56  ht
                    765: # detect cross-scope keyref and signal error
                    766: #
                    767: # Revision 1.24  2000/01/03 17:02:37  ht
                    768: # Include result of sub-ordinate key checking in overall result
                    769: # Accommodate new calling sequence for xpath.find
                    770: # add Log and Id
                    771: #
                    772: #

Webmaster