/// <summary> /// Try match the particle once. /// </summary> /// <param name="particleMatchInfo"></param> /// <param name="validationContext">The context information for validation.</param> public override void TryMatchOnce(ParticleMatchInfo particleMatchInfo, ValidationContext validationContext) { Debug.Assert(!(particleMatchInfo.StartElement is OpenXmlMiscNode)); var next = particleMatchInfo.StartElement; particleMatchInfo.LastMatchedElement = null; particleMatchInfo.Match = ParticleMatch.Nomatch; ParticleConstraint childConstraint; int constraintIndex = 0; int constraintTotal = this.ParticleConstraint.ChildrenParticles.Length; while (constraintIndex < constraintTotal && next != null) { childConstraint = this.ParticleConstraint.ChildrenParticles[constraintIndex]; // Use Reset() instead of new() to avoid heavy memory alloction and GC. _childMatchInfo.Reset(next); childConstraint.ParticleValidator.TryMatch(_childMatchInfo, validationContext); // if the _childMatchInfo.StartElement is changed, it means this method of this object is called more than once on the stack. Debug.Assert(_childMatchInfo.StartElement == next); switch (_childMatchInfo.Match) { case ParticleMatch.Nomatch: // continue trying match next child constraint. constraintIndex++; break; case ParticleMatch.Matched: particleMatchInfo.Match = ParticleMatch.Matched; particleMatchInfo.LastMatchedElement = _childMatchInfo.LastMatchedElement; return; case ParticleMatch.Partial: // partial match, incomplete children. particleMatchInfo.Match = ParticleMatch.Partial; particleMatchInfo.LastMatchedElement = _childMatchInfo.LastMatchedElement; if (validationContext.CollectExpectedChildren) { particleMatchInfo.SetExpectedChildren(_childMatchInfo.ExpectedChildren); } return; } } // no match Debug.Assert(particleMatchInfo.Match == ParticleMatch.Nomatch); return; }
/// <summary> /// Try match the particle once. /// </summary> /// <param name="particleMatchInfo"></param> /// <param name="validationContext">The context information for validation.</param> public override void TryMatchOnce(ParticleMatchInfo particleMatchInfo, ValidationContext validationContext) { Debug.Assert(!(particleMatchInfo.StartElement is OpenXmlMiscNode)); var next = particleMatchInfo.StartElement; particleMatchInfo.LastMatchedElement = null; particleMatchInfo.Match = ParticleMatch.Nomatch; ParticleConstraint childConstraint; int constraintIndex = 0; int constraintTotal = this.ParticleConstraint.ChildrenParticles.Length; while (constraintIndex < constraintTotal && next != null) { childConstraint = this.ParticleConstraint.ChildrenParticles[constraintIndex]; // Use Reset() instead of new() to avoid heavy memory alloction and GC. _childMatchInfo.Reset(next); childConstraint.ParticleValidator.TryMatch(_childMatchInfo, validationContext); // if the _childMatchInfo.StartElement is changed, it means this method of this object is called more than once on the stack. Debug.Assert(_childMatchInfo.StartElement == next); switch (_childMatchInfo.Match) { case ParticleMatch.Nomatch: // continue trying match next child constraint. constraintIndex++; break; case ParticleMatch.Matched: particleMatchInfo.Match = ParticleMatch.Matched; particleMatchInfo.LastMatchedElement = _childMatchInfo.LastMatchedElement; return; case ParticleMatch.Partial: // partial match, incomplete children. particleMatchInfo.Match = ParticleMatch.Partial; particleMatchInfo.LastMatchedElement = _childMatchInfo.LastMatchedElement; if (validationContext.CollectExpectedChildren) { particleMatchInfo.SetExpectedChildren(_childMatchInfo.ExpectedChildren); } return; } } // no match Debug.Assert(particleMatchInfo.Match == ParticleMatch.Nomatch); return; }
/// <summary> /// Try match the particle. /// </summary> /// <param name="particleMatchInfo"></param> /// <param name="validationContext">The context information for validation.</param> public override void TryMatch(ParticleMatchInfo particleMatchInfo, ValidationContext validationContext) { if (this.ParticleConstraint.MaxOccurs == 1) { this.TryMatchOnce(particleMatchInfo, validationContext); } else { int matchCount = 0; var next = particleMatchInfo.StartElement; while (next != null && this.ParticleConstraint.MaxOccursGreaterThan(matchCount)) { // Use Reset() instead of new() to avoid heavy memory alloction and GC. _childMatchInfo.Reset(next); this.TryMatchOnce(_childMatchInfo, validationContext); // if the _childMatchInfo.StartElement is changed, it means this method of this object is called more than once on the stack. Debug.Assert(_childMatchInfo.StartElement == next); if (_childMatchInfo.Match == ParticleMatch.Nomatch) { break; } else if (_childMatchInfo.Match == ParticleMatch.Matched) { matchCount++; particleMatchInfo.LastMatchedElement = _childMatchInfo.LastMatchedElement; next = validationContext.GetNextChildMc(particleMatchInfo.LastMatchedElement); } else { // return error particleMatchInfo.Match = ParticleMatch.Partial; particleMatchInfo.LastMatchedElement = _childMatchInfo.LastMatchedElement; if (validationContext.CollectExpectedChildren) { particleMatchInfo.SetExpectedChildren(_childMatchInfo.ExpectedChildren); } return; } } if (matchCount == 0) { particleMatchInfo.Match = ParticleMatch.Nomatch; if (validationContext.CollectExpectedChildren) { particleMatchInfo.SetExpectedChildren(this.GetExpectedElements()); } } else if (matchCount >= this.ParticleConstraint.MinOccurs) { // matched ok particleMatchInfo.Match = ParticleMatch.Matched; } else { if (this.GetRequiredElements(particleMatchInfo.ExpectedChildren)) { // minOccurs failed, incomplete children. particleMatchInfo.Match = ParticleMatch.Partial; } else { // all children elements are optional particleMatchInfo.Match = ParticleMatch.Matched; } } } return; }
/// <summary> /// Try match the particle once. /// </summary> /// <param name="particleMatchInfo"></param> /// <param name="validationContext">The context information for validation.</param> public override void TryMatchOnce(ParticleMatchInfo particleMatchInfo, ValidationContext validationContext) { Debug.Assert(!(particleMatchInfo.StartElement is OpenXmlMiscNode)); var next = particleMatchInfo.StartElement; particleMatchInfo.LastMatchedElement = null; particleMatchInfo.Match = ParticleMatch.Nomatch; ParticleConstraint childConstraint; int constraintIndex = 0; int constraintTotal = this.ParticleConstraint.ChildrenParticles.Length; while (constraintIndex < constraintTotal && next != null) { childConstraint = this.ParticleConstraint.ChildrenParticles[constraintIndex]; // Use Reset() instead of new() to avoid heavy memory alloction and GC. _childMatchInfo.Reset(next); childConstraint.ParticleValidator.TryMatch(_childMatchInfo, validationContext); // if the _childMatchInfo.StartElement is changed, it means this method of this object is called more than once on the stack. Debug.Assert(_childMatchInfo.StartElement == next); switch (_childMatchInfo.Match) { case ParticleMatch.Nomatch: if ( childConstraint.ParticleValidator.GetRequiredElements(null)) { if (validationContext.CollectExpectedChildren) { if (particleMatchInfo.ExpectedChildren == null) { particleMatchInfo.SetExpectedChildren(childConstraint.ParticleValidator.GetRequiredElements()); } else { // reuse same object, avoid object alloction. particleMatchInfo.ExpectedChildren.Clear(); childConstraint.ParticleValidator.GetRequiredElements(particleMatchInfo.ExpectedChildren); } } // incomplete children. if (next == particleMatchInfo.StartElement) { // the first child is not the correct one. particleMatchInfo.Match = ParticleMatch.Nomatch; particleMatchInfo.LastMatchedElement = null; return; } else { // partial match, incomplete children. particleMatchInfo.Match = ParticleMatch.Partial; return; } } else { // continue trying match next child constraint. constraintIndex++; continue; } case ParticleMatch.Matched: particleMatchInfo.LastMatchedElement = _childMatchInfo.LastMatchedElement; next = validationContext.GetNextChildMc(particleMatchInfo.LastMatchedElement); // continue trying match next child constraint. constraintIndex++; break; case ParticleMatch.Partial: // partial match, incomplete children. particleMatchInfo.Match = ParticleMatch.Partial; particleMatchInfo.LastMatchedElement = _childMatchInfo.LastMatchedElement; if (validationContext.CollectExpectedChildren) { particleMatchInfo.SetExpectedChildren(_childMatchInfo.ExpectedChildren); } return; } } if (constraintIndex == constraintTotal) { if (particleMatchInfo.LastMatchedElement != null) { particleMatchInfo.Match = ParticleMatch.Matched; } else { particleMatchInfo.Match = ParticleMatch.Nomatch; } return; } else { for (; constraintIndex < constraintTotal; constraintIndex++) { if (this.ParticleConstraint.ChildrenParticles[constraintIndex].ParticleValidator.GetRequiredElements(null)) { if (validationContext.CollectExpectedChildren) { if (particleMatchInfo.ExpectedChildren == null) { particleMatchInfo.InitExpectedChildren(); } this.ParticleConstraint.ChildrenParticles[constraintIndex].ParticleValidator.GetRequiredElements(particleMatchInfo.ExpectedChildren); } particleMatchInfo.Match = ParticleMatch.Partial; return; } } // all other children constraint are optional. particleMatchInfo.Match = ParticleMatch.Matched; return; } }
/// <summary> /// Try match the particle. /// </summary> /// <param name="particleMatchInfo"></param> /// <param name="validationContext">The context information for validation.</param> public override void TryMatch(ParticleMatchInfo particleMatchInfo, ValidationContext validationContext) { if (this.ParticleConstraint.MaxOccurs == 1) { this.TryMatchOnce(particleMatchInfo, validationContext); } else { int matchCount = 0; var next = particleMatchInfo.StartElement; while (next != null && this.ParticleConstraint.MaxOccursGreaterThan(matchCount)) { // Use Reset() instead of new() to avoid heavy memory alloction and GC. _childMatchInfo.Reset(next); this.TryMatchOnce(_childMatchInfo, validationContext); // if the _childMatchInfo.StartElement is changed, it means this method of this object is called more than once on the stack. Debug.Assert(_childMatchInfo.StartElement == next); if (_childMatchInfo.Match == ParticleMatch.Nomatch) { break; } else if (_childMatchInfo.Match == ParticleMatch.Matched) { matchCount++; particleMatchInfo.LastMatchedElement = _childMatchInfo.LastMatchedElement; next = validationContext.GetNextChildMc(particleMatchInfo.LastMatchedElement); } else { // return error particleMatchInfo.Match = ParticleMatch.Partial; particleMatchInfo.LastMatchedElement = _childMatchInfo.LastMatchedElement; if (validationContext.CollectExpectedChildren) { particleMatchInfo.SetExpectedChildren(_childMatchInfo.ExpectedChildren); } return; } } if (matchCount == 0) { particleMatchInfo.Match = ParticleMatch.Nomatch; if (validationContext.CollectExpectedChildren) { particleMatchInfo.SetExpectedChildren(this.GetExpectedElements()); } } else if (matchCount >= this.ParticleConstraint.MinOccurs) { // matched ok particleMatchInfo.Match = ParticleMatch.Matched; } else { if (this.GetRequiredElements(particleMatchInfo.ExpectedChildren)) { // minOccurs failed, incomplete children. particleMatchInfo.Match = ParticleMatch.Partial; } else { // all children elements are optional particleMatchInfo.Match = ParticleMatch.Matched; } } } return; }
/// <summary> /// Try match the particle once. /// </summary> /// <param name="particleMatchInfo"></param> /// <param name="validationContext">The context information for validation.</param> public override void TryMatchOnce(ParticleMatchInfo particleMatchInfo, ValidationContext validationContext) { Debug.Assert(!(particleMatchInfo.StartElement is OpenXmlMiscNode)); var next = particleMatchInfo.StartElement; particleMatchInfo.LastMatchedElement = null; particleMatchInfo.Match = ParticleMatch.Nomatch; ParticleConstraint childConstraint; int constraintIndex = 0; int constraintTotal = this.ParticleConstraint.ChildrenParticles.Length; while (constraintIndex < constraintTotal && next != null) { childConstraint = this.ParticleConstraint.ChildrenParticles[constraintIndex]; // Use Reset() instead of new() to avoid heavy memory alloction and GC. _childMatchInfo.Reset(next); childConstraint.ParticleValidator.TryMatch(_childMatchInfo, validationContext); // if the _childMatchInfo.StartElement is changed, it means this method of this object is called more than once on the stack. Debug.Assert(_childMatchInfo.StartElement == next); switch (_childMatchInfo.Match) { case ParticleMatch.Nomatch: if (childConstraint.ParticleValidator.GetRequiredElements(null)) { if (validationContext.CollectExpectedChildren) { if (particleMatchInfo.ExpectedChildren == null) { particleMatchInfo.SetExpectedChildren(childConstraint.ParticleValidator.GetRequiredElements()); } else { // reuse same object, avoid object alloction. particleMatchInfo.ExpectedChildren.Clear(); childConstraint.ParticleValidator.GetRequiredElements(particleMatchInfo.ExpectedChildren); } } // incomplete children. if (next == particleMatchInfo.StartElement) { // the first child is not the correct one. particleMatchInfo.Match = ParticleMatch.Nomatch; particleMatchInfo.LastMatchedElement = null; return; } else { // partial match, incomplete children. particleMatchInfo.Match = ParticleMatch.Partial; return; } } else { // continue trying match next child constraint. constraintIndex++; continue; } case ParticleMatch.Matched: particleMatchInfo.LastMatchedElement = _childMatchInfo.LastMatchedElement; next = validationContext.GetNextChildMc(particleMatchInfo.LastMatchedElement); // continue trying match next child constraint. constraintIndex++; break; case ParticleMatch.Partial: // partial match, incomplete children. particleMatchInfo.Match = ParticleMatch.Partial; particleMatchInfo.LastMatchedElement = _childMatchInfo.LastMatchedElement; if (validationContext.CollectExpectedChildren) { particleMatchInfo.SetExpectedChildren(_childMatchInfo.ExpectedChildren); } return; } } if (constraintIndex == constraintTotal) { if (particleMatchInfo.LastMatchedElement != null) { particleMatchInfo.Match = ParticleMatch.Matched; } else { particleMatchInfo.Match = ParticleMatch.Nomatch; } return; } else { for (; constraintIndex < constraintTotal; constraintIndex++) { if (this.ParticleConstraint.ChildrenParticles[constraintIndex].ParticleValidator.GetRequiredElements(null)) { if (validationContext.CollectExpectedChildren) { if (particleMatchInfo.ExpectedChildren == null) { particleMatchInfo.InitExpectedChildren(); } this.ParticleConstraint.ChildrenParticles[constraintIndex].ParticleValidator.GetRequiredElements(particleMatchInfo.ExpectedChildren); } particleMatchInfo.Match = ParticleMatch.Partial; return; } } // all other children constraint are optional. particleMatchInfo.Match = ParticleMatch.Matched; return; } }