internal XmlSchemaElement FindMatchingElement(bool bCreatingNewType, XmlReader xtr,XmlSchemaComplexType ct, ref int lastUsedSeqItem, ref bool bParticleChanged, XmlSchema parentSchema, bool setMaxoccurs)
{
if (xtr.NamespaceURI == XmlSchema.Namespace)
{
throw new XmlSchemaInferenceException(Res.SchInf_schema, 0, 0);
}
bool bItemNotUsedYet = ((lastUsedSeqItem == -1)? true: false);
XmlSchemaObjectCollection minOccursCandidates = new XmlSchemaObjectCollection(); //elements that are skipped in the sequence and need minOccurs modified.
if (ct.Particle.GetType() == typeof (XmlSchemaSequence))
{
string childURI = xtr.NamespaceURI;
if (childURI.Length == 0)
{
childURI = null;
}
XmlSchemaSequence xss = (XmlSchemaSequence) ct.Particle;
if (xss.Items.Count < 1 && !bCreatingNewType)
{
lastUsedSeqItem = 0;
XmlSchemaElement e = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema, xss.Items,-1);
e.MinOccurs = 0;
return e;
}
if (xss.Items[0].GetType() == typeof (XmlSchemaChoice))
{ // <sequence minOccurs="0" maxOccurs="unbounded"><choice><element>...</choice></sequence>
XmlSchemaChoice xsch = (XmlSchemaChoice) xss.Items[0];
foreach(XmlSchemaParticle particle in xsch.Items)
{
XmlSchemaElement el = particle as XmlSchemaElement;
if (el == null)
{
throw new XmlSchemaInferenceException(Res.SchInf_UnknownParticle, 0, 0);
}
if ((el.Name == xtr.LocalName) &&( parentSchema.TargetNamespace == childURI))
{ // element is in the same namespace
InferElement(el, false, parentSchema);
SetMinMaxOccurs(el, setMaxoccurs);
return el;
}
else if ((el.RefName.Name == xtr.LocalName) && (el.RefName.Namespace == xtr.NamespaceURI))
{
XmlSchemaElement referencedElement = FindGlobalElement(childURI, xtr.LocalName, out parentSchema);
InferElement(referencedElement, false, parentSchema);
SetMinMaxOccurs(el, setMaxoccurs);
return referencedElement;
}
}
XmlSchemaElement subElement = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema, xsch.Items,-1);
return subElement;
}
else
{ //this should be sequence of elements
int iSeqItem = 0; //iterator through schema sequence items
if (lastUsedSeqItem >= 0)
iSeqItem = lastUsedSeqItem;
XmlSchemaParticle particle = xss.Items[iSeqItem] as XmlSchemaParticle;
XmlSchemaElement el = particle as XmlSchemaElement;
if (el == null)
{
throw new XmlSchemaInferenceException(Res.SchInf_UnknownParticle, 0, 0);
}
if (el.Name == xtr.LocalName && parentSchema.TargetNamespace == childURI)
{
if (!bItemNotUsedYet) //read: if item was already used one or more times
el.MaxOccurs = decimal.MaxValue; //set it to unbounded
lastUsedSeqItem = iSeqItem;
InferElement(el, false, parentSchema);
SetMinMaxOccurs(el, false);
return el;
}
else if (el.RefName.Name == xtr.LocalName && el.RefName.Namespace == xtr.NamespaceURI)
{
if (!bItemNotUsedYet) //read: if item was already used one or more times
el.MaxOccurs = decimal.MaxValue; //set it to unbounded
lastUsedSeqItem = iSeqItem;
XmlSchemaElement referencedElement = FindGlobalElement(childURI, xtr.LocalName, out parentSchema);
InferElement(referencedElement, false, parentSchema);
SetMinMaxOccurs(el, false);
return el;
}
if (bItemNotUsedYet && el.MinOccurs!=decimal.Zero)
minOccursCandidates.Add(el);
iSeqItem++;
while (iSeqItem < xss.Items.Count)
{
particle = xss.Items[iSeqItem] as XmlSchemaParticle;
el = particle as XmlSchemaElement;
if (el == null)
{
throw new XmlSchemaInferenceException(Res.SchInf_UnknownParticle, 0, 0);
}
if (el.Name == xtr.LocalName && parentSchema.TargetNamespace == childURI)
{
lastUsedSeqItem = iSeqItem;
foreach (XmlSchemaElement minOccursElement in minOccursCandidates)
minOccursElement.MinOccurs = decimal.Zero;
InferElement(el, false, parentSchema);
SetMinMaxOccurs(el, setMaxoccurs);
return el;
}
else if (el.RefName.Name == xtr.LocalName && el.RefName.Namespace == xtr.NamespaceURI)
{
lastUsedSeqItem = iSeqItem;
foreach (XmlSchemaElement minOccursElement in minOccursCandidates)
minOccursElement.MinOccurs = decimal.Zero;
XmlSchemaElement referencedElement = FindGlobalElement(childURI, xtr.LocalName, out parentSchema);
InferElement(referencedElement, false, parentSchema);
SetMinMaxOccurs(el, setMaxoccurs);
return referencedElement;
}
minOccursCandidates.Add(el);
iSeqItem++;
}
//element not found in the sequence order, if it is found out of order change Sequence of elements to Sequence of Choices otherwise insert into sequence as optional
XmlSchemaElement subElement = null;
XmlSchemaElement actualElement = null;
if (parentSchema.TargetNamespace == childURI)
{
subElement = FindElement(xss.Items, xtr.LocalName);
actualElement = subElement;
}
else
{
subElement = FindElementRef(xss.Items, xtr.LocalName, xtr.NamespaceURI);
if (subElement != null)
{
actualElement = FindGlobalElement(childURI, xtr.LocalName, out parentSchema);
}
}
if (null != subElement)
{
XmlSchemaChoice xsc = new XmlSchemaChoice();
xsc.MaxOccurs = decimal.MaxValue;
SetMinMaxOccurs(subElement, setMaxoccurs);
InferElement(actualElement, false, parentSchema);
foreach(XmlSchemaElement copyElement in xss.Items)
{
xsc.Items.Add(CreateNewElementforChoice(copyElement));
}
xss.Items.Clear();
xss.Items.Add(xsc);
return subElement;
}
else
{
subElement = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema, xss.Items, ++lastUsedSeqItem);
if (!bCreatingNewType)
subElement.MinOccurs = decimal.Zero;
return subElement;
}
}
}
else
{
throw new XmlSchemaInferenceException(Res.SchInf_noseq, 0, 0);
}
}
internal void ProcessAttributes(ref XmlSchemaElement xse, XmlSchemaType effectiveSchemaType, bool bCreatingNewType, XmlSchema parentSchema)