internal void InferElement(XmlSchemaElement xse, bool bCreatingNewType, XmlSchema parentSchema)
{
bool bEmptyElement = xtr.IsEmptyElement;
int lastUsedSeqItem = -1;
Hashtable table = new Hashtable();
XmlSchemaType schemaType = GetEffectiveSchemaType(xse, bCreatingNewType);
XmlSchemaComplexType ct = schemaType as XmlSchemaComplexType;
//infer type based on content of the current element
if (xtr.MoveToFirstAttribute())
{
ProcessAttributes(ref xse, schemaType, bCreatingNewType, parentSchema);
}
else
{
if (!bCreatingNewType && ct != null)
{ //if type already exists and can potentially have attributes
MakeExistingAttributesOptional(ct, null);
}
}
if (ct == null || ct == XmlSchemaComplexType.AnyType) { //It was null or simple type, after processing attributes, this might have been set
ct = xse.SchemaType as XmlSchemaComplexType;
}
//xse's type is set either to complex type if attributes exist or null
if (bEmptyElement) //<element attr="3232" />
{
if (!bCreatingNewType)
{
if (null != ct)
{
if (null!= ct.Particle )
{
ct.Particle.MinOccurs = 0;
}
else if (null != ct.ContentModel)
{
XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
sce.BaseTypeName = ST_string;
sce.LineNumber = TF_string;
}
}
else if (!xse.SchemaTypeName.IsEmpty)
{
xse.LineNumber = TF_string;
xse.SchemaTypeName = ST_string;
}
}
else
{
xse.LineNumber = TF_string;
//xse.SchemaTypeName = ST_string; //My change
}
return; //We are done processing this element - all attributes are already added
}
bool bWhiteSpace = false;
do
{
xtr.Read();
if (xtr.NodeType == XmlNodeType.Whitespace)
{
bWhiteSpace = true;
}
if (xtr.NodeType == XmlNodeType.EntityReference)
{
throw new XmlSchemaInferenceException(Res.SchInf_entity, 0, 0);
}
} while( (!xtr.EOF) && (xtr.NodeType != XmlNodeType.EndElement) && (xtr.NodeType != XmlNodeType.CDATA)&&(xtr.NodeType != XmlNodeType.Element)&&(xtr.NodeType != XmlNodeType.Text) );
if (xtr.NodeType == XmlNodeType.EndElement)
{
if (bWhiteSpace) {
if (ct != null)
{
if (null != ct.ContentModel)
{
XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
sce.BaseTypeName = ST_string;
sce.LineNumber = TF_string;
}
else if (bCreatingNewType)
{
//attributes exist, but both Particle and ContentModel == null - this must be complex type with simpleContent extension
XmlSchemaSimpleContent sc = new XmlSchemaSimpleContent();
ct.ContentModel = sc;
XmlSchemaSimpleContentExtension sce = new XmlSchemaSimpleContentExtension();
sc.Content = sce;
MoveAttributes(ct, sce, bCreatingNewType);
sce.BaseTypeName = ST_string;
sce.LineNumber = TF_string;
}
else
ct.IsMixed = true;
}
else
{
xse.SchemaTypeName = ST_string;
xse.LineNumber = TF_string;
}
}
if (bCreatingNewType)
{
xse.LineNumber = TF_string;
//xse.SchemaTypeName = ST_string; //my change
}
else
{
if (null != ct)
{
if (null!= ct.Particle)
{
ct.Particle.MinOccurs = 0;
}
else if (null != ct.ContentModel)
{
XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
sce.BaseTypeName = ST_string;
sce.LineNumber = TF_string;
}
}
else if (!xse.SchemaTypeName.IsEmpty)
{
xse.LineNumber = TF_string;
xse.SchemaTypeName = ST_string;
}
}
return; //<element attr="232"></element>
}
int iChildNumber = 0;
bool bCreatingNewSequence = false;
while (!xtr.EOF && (xtr.NodeType != XmlNodeType.EndElement))
{
bool bNextNodeAlreadyRead = false; //In some cases we have to look ahead one node. If true means that we did look ahead.
iChildNumber++;
if ((xtr.NodeType == XmlNodeType.Text) || (xtr.NodeType == XmlNodeType.CDATA) ) //node can be simple type, complex with simple content or complex with mixed content
{
if (null != ct)
{
if (null != ct.Particle)
{
ct.IsMixed = true;
if (iChildNumber==1)
{
//if this is the only child and other elements do not follow, we must set particle minOccurs="0"
do{ xtr.Read();} while( (!xtr.EOF) && ((xtr.NodeType == XmlNodeType.CDATA)||(xtr.NodeType == XmlNodeType.Text) || (xtr.NodeType == XmlNodeType.Comment) || (xtr.NodeType == XmlNodeType.ProcessingInstruction) || (xtr.NodeType == XmlNodeType.Whitespace) || (xtr.NodeType == XmlNodeType.SignificantWhitespace) || (xtr.NodeType == XmlNodeType.XmlDeclaration)));
bNextNodeAlreadyRead = true;
if (xtr.NodeType == XmlNodeType.EndElement)
ct.Particle.MinOccurs=decimal.Zero;
}
}
else if (null!=ct.ContentModel)
{ //complexType with simpleContent
XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
if ((xtr.NodeType == XmlNodeType.Text) && (iChildNumber==1))
{
int SimpleType = -1;
if (xse.Parent == null)
{
SimpleType = sce.LineNumber; // we use LineNumber to represent valid type flags
}
else
{
SimpleType = GetSchemaType(sce.BaseTypeName);
xse.Parent = null;
}
sce.BaseTypeName = RefineSimpleType(xtr.Value, ref SimpleType);
sce.LineNumber = SimpleType; // we use LineNumber to represent valid type flags
}
else
{
sce.BaseTypeName = ST_string;
sce.LineNumber = TF_string;
}
}
else
{
//attributes exist, but both Particle and ContentModel == null - this must be complex type with simpleContent extension
XmlSchemaSimpleContent sc = new XmlSchemaSimpleContent();
ct.ContentModel = sc;
XmlSchemaSimpleContentExtension sce = new XmlSchemaSimpleContentExtension();
sc.Content = sce;
MoveAttributes(ct, sce, bCreatingNewType);
if (xtr.NodeType == XmlNodeType.Text)
{
int TypeFlags;
if(!bCreatingNewType)
//previously this was empty element
TypeFlags=TF_string;
else
TypeFlags = -1;
sce.BaseTypeName = RefineSimpleType(xtr.Value, ref TypeFlags);
sce.LineNumber = TypeFlags; // we use LineNumber to store flags of valid types
}
else
{
sce.BaseTypeName = ST_string;
sce.LineNumber = TF_string;
}
}
}
else
{ //node is currently empty or with SimpleType
//node will become simple type
if (iChildNumber>1)
{
//more than one consecutive text nodes probably with PI in between
xse.SchemaTypeName = ST_string;
xse.LineNumber = TF_string;// we use LineNumber to store flags of valid types
}
else
{
int TypeFlags = -1;
if (bCreatingNewType)
if (xtr.NodeType == XmlNodeType.Text)
{
xse.SchemaTypeName = RefineSimpleType(xtr.Value, ref TypeFlags);
xse.LineNumber = TypeFlags; // we use LineNumber to store flags of valid types
}
else
{
xse.SchemaTypeName = ST_string;
xse.LineNumber = TF_string;// we use LineNumber to store flags of valid types
}
else if (xtr.NodeType == XmlNodeType.Text)
{
if (xse.Parent == null)
{
TypeFlags = xse.LineNumber;
}
else
{
TypeFlags = GetSchemaType(xse.SchemaTypeName);
if (TypeFlags == -1 && xse.LineNumber == TF_string) { //Since schemaTypeName is not set for empty elements (<e></e>)
TypeFlags = TF_string;
}
xse.Parent = null;
}
xse.SchemaTypeName = RefineSimpleType(xtr.Value, ref TypeFlags); //simple type
xse.LineNumber = TypeFlags; // we use LineNumber to store flags of valid types
}
else
{
xse.SchemaTypeName = ST_string;
xse.LineNumber = TF_string;// we use LineNumber to store flags of valid types
}
}
}
}
else if (xtr.NodeType == XmlNodeType.Element)
{
XmlQualifiedName qname = new XmlQualifiedName(xtr.LocalName, xtr.NamespaceURI);
bool Maxoccursflag = false;
if (table.Contains(qname))
{
Maxoccursflag = true;
}
else
{
table.Add(qname, null);
}
if (ct==null)
{ //untill now the element was empty or SimpleType - it now becomes complex type
ct = new XmlSchemaComplexType();
xse.SchemaType = ct;
if (!xse.SchemaTypeName.IsEmpty)
{
ct.IsMixed=true;
xse.SchemaTypeName = XmlQualifiedName.Empty;
}
}
if (ct.ContentModel !=null)
{ //type was previously identified as simple content extension - we need to convert it to sequence
XmlSchemaSimpleContentExtension sce = CheckSimpleContentExtension(ct);
MoveAttributes(sce, ct);
ct.ContentModel = null;
ct.IsMixed = true;
if (ct.Particle != null)
throw new XmlSchemaInferenceException(Res.SchInf_particle, 0, 0);
ct.Particle = new XmlSchemaSequence();
bCreatingNewSequence = true;
XmlSchemaElement subelement = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema,((XmlSchemaSequence)ct.Particle).Items, -1);
lastUsedSeqItem = 0;
if (!bCreatingNewType)
ct.Particle.MinOccurs=0; //previously this was simple type so subelements did not exist
}
else if (ct.Particle == null)
{
ct.Particle = new XmlSchemaSequence();
bCreatingNewSequence = true;
XmlSchemaElement subelement = AddElement(xtr.LocalName, xtr.Prefix, xtr.NamespaceURI, parentSchema,((XmlSchemaSequence)ct.Particle).Items, -1);
if (!bCreatingNewType)
{
((XmlSchemaSequence)ct.Particle).MinOccurs = decimal.Zero;
// subelement.MinOccurs = decimal.Zero;
}
lastUsedSeqItem = 0;
}
else
{
bool bParticleChanged = false;
XmlSchemaElement subelement = FindMatchingElement(bCreatingNewType || bCreatingNewSequence, xtr, ct, ref lastUsedSeqItem, ref bParticleChanged, parentSchema, Maxoccursflag);
}
}
else if (xtr.NodeType == XmlNodeType.Text)
{
if (ct==null)
throw new XmlSchemaInferenceException(Res.SchInf_ct, 0, 0);
ct.IsMixed = true;
}
do
{
if (xtr.NodeType == XmlNodeType.EntityReference)
{
throw new XmlSchemaInferenceException(Res.SchInf_entity, 0, 0);
}
if (!bNextNodeAlreadyRead)
{
xtr.Read();
}
else
{
bNextNodeAlreadyRead = false;
}
} while( (!xtr.EOF) && (xtr.NodeType != XmlNodeType.EndElement) && (xtr.NodeType != XmlNodeType.CDATA)&&(xtr.NodeType != XmlNodeType.Element)&&(xtr.NodeType != XmlNodeType.Text));
}
if (lastUsedSeqItem != -1)
{
//Verify if all elements in a sequence exist, if not set MinOccurs=0
while (++lastUsedSeqItem < ((XmlSchemaSequence)ct.Particle).Items.Count)
{
if (((XmlSchemaSequence)ct.Particle).Items[lastUsedSeqItem].GetType() != typeof (XmlSchemaElement))
throw new XmlSchemaInferenceException(Res.SchInf_seq, 0 , 0);
XmlSchemaElement subElement = (XmlSchemaElement) ((XmlSchemaSequence)ct.Particle).Items[lastUsedSeqItem];
subElement.MinOccurs = 0;
}
}
}