Exemple #1
0
def validateKeyRefs(elt,krds):
  res=1
  for ref in krds:
    if ref.refer is None:
      break
    candidates=ref.selector.find(elt)
    if candidates:
      # print ('c', candidates,candidates[0].localName)
      if elt.keyTabs.has_key(ref.refer):
        keyTab=elt.keyTabs[ref.refer]
        if keyTab=='bogus':
          break
      else:
        elt.keyTabs[ref.refer]='bogus'
        verror(elt,
               "No key or unique constraint named %s applies below here, refed by keyref {%s}%s"%(unicode(str(ref.refer.qname),'utf-8'),ref.targetNamespace,
                                                                                                  unicode(str(ref.name),'utf-8')),
               ref.schema,"cvc-identity-constraint.2.3.2")
        break
      for s in candidates:
        keyKey=_buildKey(s,ref.fields,ref.schema)
        # print ('k',keyKey)
        if not keyKey:
          continue
	if len(keyKey)>1:
	  keyKey=tuple(keyKey)
	else:
	  keyKey=keyKey[0]
	if not keyTab.has_key(keyKey):
	  verror(s,"no key in %s for %s"%(unicode(str(ref.refer.qname),'utf-8'),
                                          unicode(keyKey)),
                 ref.schema,
                 "cvc-identity-constraint.2.3.2")
Exemple #2
0
def validateKeys1(elt,kds,reqd):
  for key in kds:
    tab={}
    candidates=key.selector.find(elt)
    if candidates:
      for s in candidates:
        keyKey=_buildKey(s,key.fields,key.schema)
        if keyKey is not None:
          if len(keyKey)>1:
            keyKey=tuple(keyKey)
          else:
            keyKey=keyKey[0]
        else:
          if reqd:
            verror(s,
                   "missing one or more fields %s from key {%s}%s"%(key.fields,
                                                                    key.targetNamespace,
                                                                unicode(str(key.name),'utf-8')),
                   key.schema,"cvc-identity-constraint.2.2.2")
          continue
	if tab.has_key(keyKey):
          if reqd:
            code="cvc-identity-constraint.2.2.3"
          else:
            code="cvc-identity-constraint.2.1.2"
	  verror(s,"duplicate key %s for {%s}%s, first appearance was %s"%
                 (unicode(keyKey),
                  key.targetNamespace,unicode(str(key.name),'utf-8'),
                  whereString(tab[keyKey].where)),
                 key.schema,code)
	else:
	  tab[keyKey]=s
          s.hasKey=1
    elt.keyTabs[key]=tab
Exemple #3
0
def checkIDTable(idTable,schema,docElt):
  for (key,val) in idTable.items():
    l=len(val)
    if l is 0:
      verror(docElt,"id %s referred to but never declared"%key,schema,
             "cvc-id.1")
    elif l is not 1:
      verror(val[1],"duplicate id %s, first appearance was %s"%(key,
                                                                whereString(val[0].where)),
             schema,
             "cvc-id.2")
Exemple #4
0
def validateElementSimple(element, type, schema, declaration):
  # check that:
  #   it has no attributes (except xsi: ones)
  #   it has one pcdata child, and if so
  #     the text of the pcdata matches the type
  if element.attributes:
    for a in element.attributes.values():
      if a.namespaceName != xsi:
        verror(element,
               "element {%s}%s with simple type not allowed attributes"%
               (element.namespaceName, element.localName),
               schema,"cvc-elt.4.1.1")
        return
#  verror(element,"xxx {%s}%s with simple type"%(element.namespaceName, element.localName),schema,"yy")

  return validateTextModel(element, type, schema, declaration)
Exemple #5
0
def validateTextModel(element, type, schema,declaration=None):
  # check that:
  #   it has one pcdata child, and if so
  #     the text of the pcdata matches the type
  name = element.localName
  text=None
  bogus=0
  if declaration is not None:
    vc=declaration.valueConstraint
  else:
    vc=None
  for child in element.children:
    if isinstance(child,XICharacters):
      if not text:
        text=child.characters
      else:
        text=text+child.characters
    elif isinstance(child,XIElement):
      verror(element,
             "element {%s}%s with simple type not allowed element children"%
             (element.namespaceName,name),schema,"cvc-complex-type.1.2.2")
      # TODO: mark this (and any others) as not validated
      return 1
  else:
    if not text:
      if vc is not None:
        if declaration.typeDefinition.simple()!=type:
          # xsi type was used, need to revalidate vc
          # TODO: should use canonical form of vcv, not original
          res=validateText(type,vc[1],element,element)
          if res is not None:
            verror(element,
                   "default doesn't satisfy xsi:type: %s%s"%(vc[1],res),
                   schema,"cvc-element.5.1.1")
        text=vc[1] # TODO: should use canonical form of vcv, not original
      else:
        text=""
    res=validateText(type,text, element, element)
    if res is not None:
      verror(element,"element content failed type check: %s%s"%(text,res),
             schema,"cvc-complex-type.1.2.2")
    elif (vc and vc[0]=='fixed' and element.actualValue!=declaration.vcv):
      verror(element,"fixed value did not match: %s!=%s"%(element.schemaNormalizedValue,vc[1]),schema,"cvc-element.5.2.2.2")
      res=1
    if res is not None:
      try:
        del element.schemaNormalizedValue
      except AttributeError:
        pass
      try:
        del element.actualValue
      except AttributeError:
        pass
    return 0
Exemple #6
0
def validateChildTypes(element, schema, lax, idTable):
  # validate each child element against its type, if we know it
  # report an error if we don't know it and it's not in <any>
  v = 1
  for child in element.children:
    if isinstance(child,XIElement):
      if child.__dict__.has_key('type') and child.type is not None:
        if child.eltDecl is not None:
          validateElement(child,child.type,schema,child.eltDecl)
        else:
          # child.type is actually a wildcard
          child.type.validate(child,schema,'element',element)
      elif lax:
        # TODO: record impact of missing type in PSVI
        validateElement(child,None,schema) # will be lax because no type
      else:
	verror(child,
               "undeclared element %s"%
               unicode(str(QName(None,child.localName,child.namespaceName or None)),'utf-8'),
               schema,"src-resolve")
      if ((child.assessedType is not None) and
          (child.validity=="valid")):
        td=child.assessedType
        if td.idt:
          if td.idt is 3:
            for ids in child.actualValue:
              if ids not in idTable:
                idTable[ids]=[]
          elif td.idt is 2:
            if child.actualValue not in idTable:
              idTable[child.actualValue]=[]
          elif td.idt is 1:
            try:
              idTable[child.actualValue].append(element)
            except KeyError:
              idTable[child.actualValue]=[element]
        if child.idTable:
          for (key,val) in child.idTable.items():
            try:
              idTable[key].extend(val)
            except KeyError:
              idTable[key]=val
  return idTable
Exemple #7
0
def validateXSIAttrs(element,schema):
  for a in element.attributes.values():
    if a.namespaceName == xsi:
      if a.localName not in ('type','nil','schemaLocation','noNamespaceSchemaLocation'):
        verror(element,"unknown xsi attribute %s" % a.localName,schema,
               "cvc-complex-type.1.3")
        a.type=None
      else:
        a.type=schema.sschema.sforsi.attributeTable[a.localName]
        res=validateText(a.type.typeDefinition,
                         a.normalizedValue,a,element)
        a.assessedType = a.type.typeDefinition
        if res is not None:
          verror(element,
                 "attribute type check failed for %s: %s%s"%(a.localName,
                                                             a.normalizedValue,
                                                             res),
                 schema,'cvc-attribute.1.2',0,None,a)
        else:
          a.schemaNormalizedValue=a.normalizedValue
      a.assess(schema.sschema,a.type)
Exemple #8
0
def _buildKey(s,fps,schema):
  keyKey=[]
  for fp in fps:
    kv=fp.find(s)
    if kv:
      # print ('f', kv,kv[0].localName)
      if len(kv)>1:
        verror(s,"Field XPath %s produced multiple hits"%fp.str,
               schema,
               "cvc-identity-constraint.3")
      if kv[0].assessedType is None:
        # has to have been validated OK to be used
        return 
      if isinstance(kv[0],Element):
        try:
          nulla=kv[0].attributes[(xsi,"nil")]
          if (nulla.validity=='valid' and
              nulla.schemaNormalizedValue == "true"):
            # pretend not here -- key will error, others OK -- NOT IN REC!!!
            return
        except KeyError:
          pass
        try:
          keyKey.append(_hashable(kv[0].actualValue))
        except AttributeError:
          # TODO: is this really OK, i.e. mixed content?
          if (len(kv[0].children)>0 and
              isinstance(kv[0].children[0],Characters)):
            keyKey.append(kv[0].children[0].characters)
          else:
            # XPath says in this case value is the empty string
            keyKey.append("")
      elif isinstance(kv[0],Attribute):
        keyKey.append(_hashable(kv[0].actualValue))
      else:
        # TODO error or shouldnt?
        vwarn(s,"oops, key value %s:%s"%(type(kv[0]),kv[0]),schema)
    else:
      return
  return keyKey
Exemple #9
0
def assignAttributeTypes(element, attrdefs, extendable, schema, lax):
  # look up each attribute in attrdefs and assign its type
  # error if attr declaration is not found and type is not extendable
#  print "assigning attrs for %s {%s}%s" % (element.originalName, element.namespaceName, element.localName)
#  print "declared attrs are:"
#  for zz in attrdefs.keys():
#    if isinstance(zz, QName):
#      print "{%s}%s " % (zz.uri, zz.local)
#    else:
#      print zz
  element.attrTable={}
  for a in element.attributes.values():
#    print "assigning attr %s {%s}%s,%s,%s" % (a.originalName, a.namespaceName, a.localName,lax,attrdefs.has_key("#any"))
    ansn=a.namespaceName
    an=QName(None,a.localName,ansn or None)
    element.attrTable[an]=a
    if ansn == xsi:
      continue
    elif attrdefs.has_key(an):
      a.type = attrdefs[an]
    elif lax:
      if ansn:
        schema.sschema.tryHardForDecl(a.localName,ansn,'attribute',schema,a)
        if schema.vAttributeTable.has_key(an):
          a.type=schema.vAttributeTable[an]
        else:
          a.type=None
      else:
        a.type=None
    elif (attrdefs.has_key("#any") and
          attrdefs["#any"].attributeDeclaration.allows(ansn or None)):
      a.type = attrdefs["#any"].attributeDeclaration
    else:
      verror(element,"undeclared attribute %s" % unicode(str(an),'utf-8'),schema,
               "cvc-complex-type.1.3")
      a.type = None
  return
Exemple #10
0
def validateAttributeTypes(element,attrs, attrdefs, schema):
  # check that each attribute matches its type
  # check that all required attributes are present
  for (adq,ad) in attrdefs.items():
    if not attrs.has_key(adq):
      if ad.minOccurs==1:
        verror(element,"required attribute %s not present"%unicode(str(adq),'utf-8'),schema,
               'cvc-complex-type.1.4')
      vc=ad.valueConstraint
      if ((vc is None) and
          isinstance(ad.attributeDeclaration,Attribute)):
        vc=ad.attributeDeclaration.valueConstraint
      if vc is not None:
        na=XIAttribute(element,adq.uri,adq.local,None,
                                        vc[1], # hack, not called for by REC
                                        0)
        na.actualValue=ad.vcv
        na.schemaNormalizedValue=vc[1]  # should be canon val for actualVal
        na.assessedType=na.typeDefinition=ad.attributeDeclaration.typeDefinition
        na.attributeDeclaration=ad.attributeDeclaration
        na.validity='valid'
        na.validationAttempted='full'
        na.validationContext=schema.sschema.docElt
        element.addAttribute(na)
  idTable={}
  xss=schema.sschema.sfors
  for (an,a) in attrs.items():
    if an.uri==xsi:
      # handled already
      continue
    elif a.type is not None:
      if isinstance(a.type,AttributeUse):
        ad=a.type.attributeDeclaration
        td=ad.typeDefinition
        if a.type.valueConstraint is None:
          vc=ad.valueConstraint
        else:
          vc=a.type.valueConstraint
      else:
        ad=a.type
        if not isinstance(ad,Wildcard):
          td=ad.typeDefinition
          vc=ad.valueConstraint
        else:
          vc=None
      if isinstance(ad,Wildcard):
        res=ad.validate(a,schema,'attribute',element)
      else:
        if td is not None:
          res=validateText(td,a.normalizedValue,a,element)
          if res is None:
            a.assessedType = td
            if td.idt:
              if td.idt is 3:
                for ids in a.actualValue:
                  idTable[ids]=[]
              elif td.idt is 2:
                idTable[a.actualValue]=[]
              elif td.idt is 1:
                idTable[a.actualValue]=[element]
            if (vc is not None) and vc[0]=='fixed':
              if a.actualValue!=a.type.vcv:
                verror(element,"fixed value did not match for attribute %s: %s!=%s"%(unicode(str(an),'utf-8'),
                                                                                     a.normalizedValue,vc[1]),schema,"cvc-attribute.1.3")
        else:
          res=None
      if res is not None:
        verror(element,"attribute type check failed for %s: %s%s"%(unicode(str(an),'utf-8'),
                                                                   a.normalizedValue,
                                                                   res),
               schema,'cvc-attribute.1.2',0,None,a)
        a.schemaNormalizedValue=None
    else:
      ad=None
    a.assess(schema.sschema,ad)
  return idTable
Exemple #11
0
def av(self,child,schema,kind,elt):
  q = QName(None,child.localName,child.namespaceName or None)
  if kind=='element':
    kinde='child'
  else:
    kinde=kind
  vwarn(elt,"allowing %s as %s because it matched wildcard(%s)" %
        (unicode(str(q),'utf-8'),kinde,self.allowed),schema)
  if self.processContents!='skip':
#   print "looking for decl for %s" % child.originalName
    schema.sschema.tryHardForDecl(child.localName,
                                  child.namespaceName,kind,schema,child)
    if schema.sschema.schemas.has_key(child.namespaceName):
      try:
        if kind=='element':
          e = schema.vElementTable[q]
        else:
          e = schema.vAttributeTable[q]
      except KeyError:
        e=None
  #     print "decl for %s is %s" % (child.originalName, e)
      if (e is not None) and (e.typeDefinition is not None):
        vwarn(None,"validating it against %s" %
                unicode(str(e.typeDefinition.name or 'anonymous type'),'utf-8'),
              schema)
        if kind=='element':
          validateElement(child, e.typeDefinition, schema, e)
          return
        else:
          child.assessedType = e.typeDefinition
          res=validateText(e.typeDefinition,child.normalizedValue,
                           child, elt)
          # TODO: check child.vc for fixed
          if res is not None:
            verror(elt,
                   "attribute type check failed for %s: %s%s"%(unicode(str(q),'utf-8'),
                                                               child.normalizedValue,
                                                               res),
                   schema,'cvc-attribute.1.2',0,None,child)
            child.schemaNormalizedValue=None
          return
      elif (self.processContents=='strict' and
            not (kind=='element' and child.attributes.has_key((xsi, "type")))):
        # TODO check this against actual def'n of missing component
        losing=1
      elif kind=='element':
        losing=0
      else:
        # lax attribute, I think
        return
    else:
      schema.sschema.losingNamespaces[child.namespaceName]=1
      if self.processContents=='strict':
        losing=1
      else:
        losing=0
    if losing:
      verror(elt,
             "can't find a type for wildcard-matching %s %s" %(kinde,
                                                               unicode(str(q),'utf-8')),
             schema,
             "src-resolve")
    if kind=='element':
      vwarn(None,"validating it %sly"%self.processContents,schema)
      validateElement(child,None,schema,0)
Exemple #12
0
def validateElement(element, type, schema, eltDecl=None):
  sschema=schema.sschema
  element.idTable=None
  if eltDecl is None and type is None:
    # note if we come from a wildcard that's already failed to find a decl,
    # we don't try again, because eltDecl is 0 in that case
    nsn=element.namespaceName
    eqn=QName(None,element.localName,nsn or None)
    sschema.tryHardForDecl(element.localName,nsn,
                                  'element',schema,element)
    if schema.vElementTable.has_key(eqn):
      eltDecl=schema.vElementTable[eqn]
      if eltDecl is not None:
        type=eltDecl.typeDefinition
  if eltDecl==0:
    eltDecl=None
  validateXSIAttrs(element,schema)
  if isinstance(eltDecl,Element):
     # TODO: is this right if no eltDecl -- think so -- need erratum??
    nullable =  eltDecl.nullable
  else:
    nullable = 1  
  nulled = 0
  if sschema.checkingSchema and element.localName=='import':
    if element.attributes.has_key((None,"namespace")):
      ins=element.attributes[(None,"namespace")].normalizedValue
    else:
      ins=None
    sschema.allowedNamespaces.append(ins)
  if element.attributes.has_key((xsi, "nil")):
    if not nullable:
      verror(element,
             "xsi:nil specified on non-nillable element %s" % element.originalName,
             schema,"cvc-elt.1.1")
      element.assess(sschema,eltDecl)
      return
    nulla=element.attributes[(xsi,"nil")]
    nulled = (nulla.validity=='valid' and
              nulla.schemaNormalizedValue == "true")
  if element.attributes.has_key((xsi, "type")):
    xsitype=None
    typea=element.attributes[(xsi, "type")]
    if typea.validity=='valid':
      t = typea.schemaNormalizedValue;
      (tp,tl) = splitQName(t)
      # because the attribute, a QName, is valid, the prefix, even
      # if it's None, must be bound
      if element.inScopeNamespaces.has_key(tp):
        qt = QName(tp,
                   tl, element.inScopeNamespaces[tp].namespaceName)
      else:
        qt= QName(tp,tl,None)
      if schema.vTypeTable.has_key(qt):
        xsitype=schema.vTypeTable[qt]
        if type is not None and not xsitype.isSubtype(type,type.final):
          verror(element,
             "xsi:type %s is not a subtype of the declared type %s"%(unicode(str(qt),'utf-8'),
                                                                     unicode(str(type.name),'utf-8')),
                 schema,"cvc-elt.2.3")
        elif type is not None:
          vwarn(element,
                "using xsi:type %s instead of original %s" % (unicode(str(qt),'utf-8'),
                                                              unicode(str(type.name),'utf-8')),
                schema)
      else:
        verror(element,"xsi:type %s undefined" % unicode(str(qt),'utf-8'),schema,"cvc-elt.2.2")
    else:
      qt=typea.normalizedValue
    if xsitype is None:
      if type is None:
        vwarn(element,"xsi:type %s didn't yield a type" % unicode(str(qt),'utf-8'),schema)
      else:
        vwarn(element,
              "xsi:type %s didn't yield a type, using original %s" % (unicode(str(qt),'utf-8'),
                                                                      unicode(str(type.name),'utf-8')),
              schema)
    else:
      # TODO: enforce {disallowed substitutions}
      type = xsitype
  element.assessedType = type
  element.lax = lax = type is None
  # might have none in case of recursive call inside <any/>, or at top level,
  # or after errors
  if nulled:
    validateElementNull(element, type, schema)
  if type is not None:
    # TODO: check element is not abstract
    if ((type is not Type.urType) and
        (isinstance(type, AbInitio) or
         isinstance(type, SimpleType))):
      if not nulled:
        validateElementSimple(element, type, schema, eltDecl)
      if isinstance(eltDecl,Element):
        validateKeys(eltDecl,element)
      element.assess(sschema,eltDecl)
      return
    # a complexType
    if type.abstract=='true':
      verror(element,"attempt to use abstract type %s to validate"%unicode(str(type.name),'utf-8'),
             schema,'cvc-complex-type.1')
      element.assess(sschema,eltDecl)
      return
    ad=type.attributeDeclarations
    ps=type.prohibitedSubstitutions
  else:
    ps=[]
    ad={}
  assignAttributeTypes(element, ad, ps, schema, lax)
  idTable=validateAttributeTypes(element, element.attrTable, ad, schema)
  #  print "assigning types for %s" % element.originalName
  if not nulled:
    # we must look at the content model before checking the types, so that
    # we know which children matched <any>
    if type is not None:
      noSubTypes=validateContentModel(element, type, schema, eltDecl)
    idTable=validateChildTypes(element, schema, lax or noSubTypes, idTable)
  if isinstance(eltDecl,Element):
    validateKeys(eltDecl,element)
  element.idTable=idTable
  if sschema.docElt==element:
    checkIDTable(idTable,schema,element)
  element.assess(schema.sschema,eltDecl)
Exemple #13
0
def validateElementModel(element, fsm, mixed, schema, declaration):
  #  print "validating element model for %s" % element.originalName
  if fsm is None:
    return
  fsm.initCounters()
  n = fsm.startNode
  #sys.stdout.write("|%s"%n.id)
  text = None
  qname = None
  for c in element.children:
    if isinstance(c,XICharacters):
      if mixed:
        if not text:
          text=c.characters
        else:
          text=text+c.characters
      elif not _whitespace.match(c.characters):
	verror(element,
               "text not allowed: |%s|" % c.characters,
               schema,"cvc-complex-type.1.2.3")
	return 1
    elif isinstance(c,XIElement):
      l=n.edges
      i=len(l)-1
      while i>=0:
        e=l[i]
        m = e.match(c)
        if m is not None:
          # success
          n = m
          #sys.stdout.write("-%s->%s"%(unicode(e),m.id))
          if e.__class__ is IncrEdge:
            l=m.edges
            i=len(l)-1
            continue
          if e.decl is not None:
            if isinstance(e.decl, Wildcard):
              c.type = e.decl
              c.eltDecl=None                # not used so don't leave around
              c.strict = (e.decl.processContents == 'strict')
            else:
              c.strict = 1
              c.eltDecl=e.decl
              c.type = c.eltDecl.typeDefinition
          else:
            c.strict = 1
            c.type = None
          break
        i=i-1
      else:
        allowed=[]
        c.type=None
        for e in n.edges:
          eq=unicode(str(e),'utf-8')
          if eq!="L":
            allowed.append(eq)
        fx=fsm.asXML()
        verror(c,
               "element %s not allowed here (%s) in element %s, expecting [%s]:\n"%
               (unicode(str(QName(None, c.localName, c.namespaceName or None)),'utf-8'), n.id,
                unicode(str(QName(None,element.localName,element.namespaceName or None)),'utf-8'),
               ",".join(allowed)),
               schema,"cvc-complex-type.1.2.4",0,fx,element)
        return 1
  l=n.edges
  i=len(l)-1
  # Must go backwards, to get ++ edges first
  #sys.stdout.write("$$")
  while i>=0:
    e=l[i]
    x=e.matchEnd()
    if x is None:
      #sys.stdout.write("N")
      i=i-1
      continue
    if x.__class__ is FSMNode:
      n=x
      #sys.stdout.write("-%s->%s"%(unicode(e),x.id))
      l=x.edges
      i=len(l)-1
      continue
    if x==True:
      #sys.stdout.write("-%s->|\n"%unicode(e))
      break
    if x==False:
      #sys.stdout.write("F")
      i=i-1
      continue
    #sys.stdout.write("e")
    verror(element,x.errmsg,schema,"cvc-complex-type.1.2.4")
    i=i-1
  else:
    allowed=[]
    for e in n.edges:
      eq=unicode(str(e),'utf-8')
      if eq!="L":
        allowed.append(eq)
    fx=fsm.asXML()
    verror(element,
           "content of %s is not allowed to end here (%s), expecting %s:\n"%
           (element.originalName,n.id,allowed),
           schema,"cvc-complex-type.1.2.4",1,fx)
  if declaration is not None:
    vc=declaration.valueConstraint
  else:
    vc=None
  if vc is not None:
    if qname:
      # there were element children
      if vc[0]=='fixed':
        verror(element,
               "element content not allowed with 'fixed' value constraint'",
               schema,"cvc-element.5.2.2.1")
    else:
      # empty or only text
      if text is None:
        element.schemaNormalizedValue=element.actualValue=vc[1]
      else:
        # content
        if vc[0]=='fixed':
          if text==vc[1]:
            element.schemaNormalizedValue=element.actualValue=vc[1]
          else:
            verror(element,
                   "fixed value did not match: %s!=%s"%(text,vc[1]),
                   schema,"cvc-element.5.2.2.2")
  return 0 
Exemple #14
0
def validateEmptyModel(element, type, schema):
  if len(element.children) != 0:
    verror(element,"element %s must be empty but is not" % element.originalName,schema,
           "cvc-complex-type.1.2")
    return 1
  return 0
Exemple #15
0
def validateElementNull(element, type, schema):
  if len(element.children) != 0:
    verror(element,"element %s is nilled but is not empty" % element.originalName,
           schema,"cvc-elt.1.2.1")
  else:
    element.null=1