diff options
-rw-r--r-- | examples/ooxml-strict/dumpsample.py | 5 | ||||
-rw-r--r-- | pyxb/binding/basis.py | 2 | ||||
-rw-r--r-- | pyxb/binding/content.py | 65 |
3 files changed, 49 insertions, 23 deletions
diff --git a/examples/ooxml-strict/dumpsample.py b/examples/ooxml-strict/dumpsample.py index f0cf8cf..d9ceba8 100644 --- a/examples/ooxml-strict/dumpsample.py +++ b/examples/ooxml-strict/dumpsample.py @@ -32,6 +32,7 @@ else: iteration=1 for (fragment, mimetype, schema, reltype) in package.files(worklist.mimetypes): + print fragment saxer = pyxb.binding.saxer.make_parser(location_base=fragment) handler = saxer.getContentHandler() saxer.parse(StringIO.StringIO(package.read(fragment))) @@ -45,3 +46,7 @@ else: package.copyWithReplace(currOutFile,{fragment: sax_instance.toxml().encode('utf-8')}) iteration += 1 print "Written "+currOutFile + + saxer = pyxb.binding.saxer.make_parser(location_base=fragment) + handler = saxer.getContentHandler() + saxer.parse(StringIO.StringIO(sax_instance.toxml().encode('utf-8'))) diff --git a/pyxb/binding/basis.py b/pyxb/binding/basis.py index 5305955..d0a3c30 100644 --- a/pyxb/binding/basis.py +++ b/pyxb/binding/basis.py @@ -1859,6 +1859,8 @@ class complexTypeDefinition (_TypeBinding_mixin, utility._DeconflictSymbols_mixi try: order = self._validatedChildren() except Exception, e: + print type(self) + order = self._validatedChildren() raise pyxb.BindingValidationError('Error matching content to binding model: %s' % (e,)) if order is None: raise pyxb.BindingValidationError('Unable to match content to binding model') diff --git a/pyxb/binding/content.py b/pyxb/binding/content.py index 3299657..2bcb40e 100644 --- a/pyxb/binding/content.py +++ b/pyxb/binding/content.py @@ -129,7 +129,7 @@ class ContentModel_mixin (pyxb.cscRoot): symbol_set_out.update(symbol_set_new) output_sequence_out[:] = output_sequence_new - def _validate (self, symbol_set, output_sequence): + def _validate (self, symbol_set, output_sequence, d): """Determine whether an output sequence created from the symbols can be made consistent with the model. @@ -642,9 +642,9 @@ class ElementUse (ContentState_mixin, ContentModel_mixin): #print '%s %s %s in %s' % (instance, value, element_use, self) return False - def _validate (self, symbol_set, output_sequence): + def _validate (self, symbol_set, output_sequence, d): values = symbol_set.get(self) - #print 'values %s' % (values,) + print reduce(lambda a,b: a+b,[' ' for i in range(d)],' ')+'ElementUse._validate: values %s' % (values,) if values is None: return False used = values.pop(0) @@ -755,9 +755,10 @@ class Wildcard (ContentState_mixin, ContentModel_mixin): particle_state.incrementCount() return True - def _validate (self, symbol_set, output_sequence): + def _validate (self, symbol_set, output_sequence, d): # @todo check node against namespace constraint and process contents #print 'WARNING: Accepting node as wildcard match without validating.' + print reduce(lambda a,b: a+b,[' ' for i in range(d)],' ')+"Wildcard._validate" wc_values = symbol_set.get(None) if wc_values is None: return False @@ -938,9 +939,9 @@ class ParticleState (pyxb.cscRoot): # @TODO@ Set a flag so we can make verifyComplete safe to call # multiple times? #print 'PS.VC %s entry' % (self,) - if not self.__particle.satisfiesOccurrences(self.__count): + if not self.__particle.satisfiesOccurrences(self.__count,0): self.__termState._verifyComplete(self) - if not self.__particle.satisfiesOccurrences(self.__count): + if not self.__particle.satisfiesOccurrences(self.__count,0): print 'PS.VC %s incomplete' % (self,) raise pyxb.MissingContentError('incomplete') if self.__parentState is not None: @@ -1000,7 +1001,7 @@ class ParticleState (pyxb.cscRoot): raise pyxb.UnexpectedElementError('too many') else: if self.__parentState is not None: - self.__parentState.notifyFailure(self, self.__particle.satisfiesOccurrences(self.__count)) + self.__parentState.notifyFailure(self, self.__particle.satisfiesOccurrences(self.__count,0)) if not self.__particle.meetsMinimum(self.__count): # @TODO@ Use better exception; changing this will require # changing some unit tests. @@ -1029,9 +1030,10 @@ class ParticleModel (ContentModel_mixin): occurrences""" return count >= self.__minOccurs - def satisfiesOccurrences (self, count): + def satisfiesOccurrences (self, count, blah): """@return: C{True} iff the provided count satisfies the occurrence requirements""" + print reduce(lambda a,b: a+b,[' ' for i in range(blah)],' ')+"satisfiesOccurrences: %d %s %s" % (count,self.__minOccurs,self.__maxOccurs) return self.meetsMinimum(count) and self.meetsMaximum(count) def __init__ (self, term, min_occurs=1, max_occurs=1): @@ -1067,23 +1069,27 @@ class ParticleModel (ContentModel_mixin): """ output_sequence = [] - #print 'Start: %d %s %s : %s' % (self.__minOccurs, self.__maxOccurs, self.__term, symbol_set) - result = self._validate(symbol_set, output_sequence) - #print 'End: %s %s %s' % (result, symbol_set, output_sequence) + print 'Start: %d %s %s : %s' % (self.__minOccurs, self.__maxOccurs, self.__term, symbol_set) + result = self._validate(symbol_set, output_sequence, 0) + print 'End: %s %s %s' % (result, symbol_set, output_sequence) if result: return (symbol_set, output_sequence) return None - def _validate (self, symbol_set, output_sequence): + def __str__ (self): + return 'PM.%s@%x' % (self.__term, id(self)) + + def _validate (self, symbol_set, output_sequence, d): symbol_set_mut = self._validateCloneSymbolSet(symbol_set) output_sequence_mut = self._validateCloneOutputSequence(output_sequence) count = 0 - #print 'VAL start %s: %d %s' % (self.__term, self.__minOccurs, self.__maxOccurs) + print reduce(lambda a,b: a+b,[' ' for i in range(d)],' ')+'VAL start %s (%s): %d %s' % (self.__term, type(self.__term), self.__minOccurs, self.__maxOccurs) last_size = len(output_sequence_mut) - while (count != self.__maxOccurs) and self.__term._validate(symbol_set_mut, output_sequence_mut): - #print 'VAL %s old cnt %d, left %s' % (self.__term, count, symbol_set_mut) + while (count != self.__maxOccurs) and self.__term._validate(symbol_set_mut, output_sequence_mut,d+1): + print reduce(lambda a,b: a+b,[' ' for i in range(d)],' ')+'VAL %s old cnt %d, left %s, used %s' % (self.__term, count, symbol_set_mut, output_sequence_mut) this_size = len(output_sequence_mut) if this_size == last_size: + print reduce(lambda a,b: a+b,[' ' for i in range(d)],' ')+"Validated without consuming anything" # Validated without consuming anything. Assume we can # continue to do so, jump to the minimum, and exit. if count < self.__minOccurs: @@ -1091,10 +1097,11 @@ class ParticleModel (ContentModel_mixin): break count += 1 last_size = this_size - result = self.satisfiesOccurrences(count) + result = self.satisfiesOccurrences(count,d) if (result): + print reduce(lambda a,b: a+b,[' ' for i in range(d)],' ')+"Running _validateReplaceResults" self._validateReplaceResults(symbol_set, symbol_set_mut, output_sequence, output_sequence_mut) - #print 'VAL end PRT %s res %s: %s %s %s' % (self.__term, result, self.__minOccurs, count, self.__maxOccurs) + print reduce(lambda a,b: a+b,[' ' for i in range(d)],' ')+'VAL end PRT %s res %s: %s %s %s %s %s' % (self.__term, result, self.__minOccurs, count, self.__maxOccurs, symbol_set, output_sequence) return result class _Group (ContentModel_mixin): @@ -1117,11 +1124,13 @@ class _Group (ContentModel_mixin): return self._StateClass(self, parent_particle_state) # All and Sequence share the same validation code, so it's up here. - def _validate (self, symbol_set, output_sequence): + def _validate (self, symbol_set, output_sequence, d): symbol_set_mut = self._validateCloneSymbolSet(symbol_set) output_sequence_mut = self._validateCloneOutputSequence(output_sequence) + print reduce(lambda a,b: a+b,[' ' for i in range(d)],' ')+'VAL group start %s (%s)' % (self, type(self)) for p in self.particles(): - if not p._validate(symbol_set_mut, output_sequence_mut): + if not p._validate(symbol_set_mut, output_sequence_mut,d+1): + print "VAL group: failed" return False self._validateReplaceResults(symbol_set, symbol_set_mut, output_sequence, output_sequence_mut) return True @@ -1131,17 +1140,27 @@ class GroupChoice (_Group): _StateClass = ChoiceState # Choice requires a different validation algorithm - def _validate (self, symbol_set, output_sequence): + def _validate (self, symbol_set, output_sequence, d): reset_mutables = True + latent_success = False + print reduce(lambda a,b: a+b,[' ' for i in range(d)],' ')+'VAL group choice start %s (%s), particles (%d) %s' % (self, type(self), len(self.particles()), self.particles()) for p in self.particles(): + print reduce(lambda a,b: a+b,[' ' for i in range(d)],' ')+' - group choice reset mutables %s' % (reset_mutables,) if reset_mutables: symbol_set_mut = self._validateCloneSymbolSet(symbol_set) output_sequence_mut = self._validateCloneOutputSequence(output_sequence) - if p._validate(symbol_set_mut, output_sequence_mut): + if p._validate(symbol_set_mut, output_sequence_mut,d+1): + print reduce(lambda a,b: a+b,[' ' for i in range(d)],' ')+"validation succeeded" + print reduce(lambda a,b: a+b,[' ' for i in range(d)],' ')+"Running _validateReplaceResults" self._validateReplaceResults(symbol_set, symbol_set_mut, output_sequence, output_sequence_mut) - return True + latent_success = True + # be greedy - if we find something that consumes a symbol, take it + if len(output_sequence) != len(output_sequence_mut): + return True + else: + print reduce(lambda a,b: a+b,[' ' for i in range(d)],' ')+"validation failed" reset_mutables = len(output_sequence) != len(output_sequence_mut) - return False + return latent_success class GroupAll (_Group): _StateClass = AllState |