private void ReadElementElement (DataRow row)
{
// This child element (for row) might be either simple
// content element, or child element
// MS.NET crashes here... but it seems just a bug.
DataColumn col = row.Table.Columns [XmlHelper.Decode (reader.LocalName)];
if (col == null || col.Namespace != reader.NamespaceURI)
col = null;
// if col exists, then it should be MappingType.Element
if (col != null
&& col.ColumnMapping == MappingType.Element) {
// TODO: This part is suspicious for
// MS compatibility (test required)
if (col.Namespace != reader.NamespaceURI) {
reader.Skip ();
return;
}
bool wasEmpty = reader.IsEmptyElement;
int depth = reader.Depth;
if (typeof (IXmlSerializable).IsAssignableFrom (col.DataType)) {
#if NET_2_0
try {
// NOTE: ReadElementString works fine with proper XML with CDATA etc,
// however doesn't behave well with XMLs like the one in
// https://bugzilla.novell.com/show_bug.cgi?id=377146 which is
// apparently supported by MS.NET - to maintain compatibility,
// If the obj implements IXmlSerializable, let obj's ReadXml do the reading
IXmlSerializable obj = (IXmlSerializable) Activator.CreateInstance (col.DataType, new object [0]);
if (!reader.IsEmptyElement) {
obj.ReadXml (reader);
reader.ReadEndElement ();
} else {
reader.Skip ();
}
row [col] = obj;
} catch (XmlException e) {
#endif
// XML is not in accordance to expected standards, try reading the content as an xml doc
row [col] = reader.ReadInnerXml ();
#if NET_2_0
} catch (InvalidOperationException e) {
row [col] = reader.ReadInnerXml ();
}
#endif
} else {
row [col] = StringToObject (col.DataType, reader.ReadElementString ());
}
if (!wasEmpty && reader.Depth > depth) {
// This means, instance does not match with
// the schema (because the instance element
// contains complex content, while specified as
// simple), so just skip to the end of the
// element.
while (reader.Depth > depth)
reader.Read ();
reader.Read ();
}
reader.MoveToContent ();
return;
} else if (col != null) {
// Mismatch column type. Just skip
reader.Skip ();
reader.MoveToContent ();
return;
}
// Otherwise, it might be child table element
DataRelationCollection rels = row.Table.ChildRelations;
for (int i = 0; i < rels.Count; i++) {
DataRelation rel = rels [i];
if (!rel.Nested)
continue;
DataTable ct = rel.ChildTable;
if (ct.TableName != XmlHelper.Decode (reader.LocalName) || ct.Namespace != reader.NamespaceURI)
continue;
DataRow childRow = rel.ChildTable.NewRow ();
ReadElement (childRow);
for (int c = 0; c < rel.ChildColumns.Length; c++) {
childRow [rel.ChildColumns [c]]
= row [rel.ParentColumns [c]];
}
rel.ChildTable.Rows.Add (childRow);
return;
}
// Matched neither of the above: just skip
reader.Skip ();
reader.MoveToContent ();
}