public XdtoObjectType(XmlSchemaComplexType xmlType, XdtoFactory factory) { Name = xmlType.QualifiedName.Name; NamespaceUri = xmlType.QualifiedName.Namespace; Abstract = xmlType.IsAbstract; Mixed = xmlType.IsMixed; var properties = new List <XdtoProperty> (); var particle = xmlType.Particle; if (xmlType.ContentModel is XmlSchemaComplexContent) { var complexContent = xmlType.ContentModel as XmlSchemaComplexContent; if (complexContent.Content is XmlSchemaComplexContentExtension) { var extension = complexContent.Content as XmlSchemaComplexContentExtension; BaseType = factory.Type(Normalize(extension.BaseTypeName, NamespaceUri)) as XdtoObjectType; particle = extension.Particle; } else { throw new NotImplementedException("Недоработочка в XDTO-объекте"); } } if (particle is XmlSchemaSequence) { var sequence = particle as XmlSchemaSequence; foreach (var item in sequence.Items) { var element = item as XmlSchemaElement; IXdtoType propertyType; if (!element.SchemaTypeName.IsEmpty) { propertyType = new TypeResolver(factory, element.SchemaTypeName); } else { var type = element.SchemaType; if (type is XmlSchemaSimpleType) { propertyType = new XdtoValueType(type as XmlSchemaSimpleType, factory); } else if (type is XmlSchemaComplexType) { propertyType = new XdtoObjectType(type as XmlSchemaComplexType, factory); } else { propertyType = new XdtoObjectType(); } } var minOccurs = element.MinOccurs; var maxOccurs = string.Equals(element.MaxOccursString, "unbounded", StringComparison.Ordinal) ? -1 : element.MaxOccurs ; properties.Add(new XdtoProperty(this, null, XmlFormEnum.Element, element.QualifiedName.Namespace, element.QualifiedName.Name, (int)minOccurs, (int)maxOccurs, propertyType)); } } else if (particle is XmlSchemaChoice) { var choice = particle as XmlSchemaChoice; foreach (var item in choice.Items) { var element = item as XmlSchemaElement; // TODO: копипаста IXdtoType propertyType; if (!element.SchemaTypeName.IsEmpty) { propertyType = new TypeResolver(factory, element.SchemaTypeName); } else { var type = element.SchemaType; if (type is XmlSchemaSimpleType) { propertyType = new XdtoValueType(type as XmlSchemaSimpleType, factory); } else if (type is XmlSchemaComplexType) { propertyType = new XdtoObjectType(type as XmlSchemaComplexType, factory); } else { throw new NotImplementedException("Anonymous type..."); } } properties.Add(new XdtoProperty(this, null, XmlFormEnum.Element, element.QualifiedName.Namespace, element.QualifiedName.Name, 0, 1, propertyType)); } } else { throw new NotImplementedException("Недоработочка в XDTO-объекте"); } Properties = new XdtoPropertyCollection(properties); }
public IXdtoType Resolve() { return(_factory.Type(_xmlType)); }
public IXdtoValue ReadXml(XmlReaderImpl reader, IXdtoType expectedType, XdtoFactory factory) { // TODO: дублирование кода в трёх ветках var result = new XdtoDataObject(this, null, null); // TODO: Перевести XML на простые перечисления var xmlNodeTypeEnum = XmlNodeTypeEnum.CreateInstance(); var xmlElementStart = xmlNodeTypeEnum.FromNativeValue(System.Xml.XmlNodeType.Element); var xmlText = xmlNodeTypeEnum.FromNativeValue(System.Xml.XmlNodeType.Text); var xmlElementEnd = xmlNodeTypeEnum.FromNativeValue(System.Xml.XmlNodeType.EndElement); while (reader.ReadAttribute()) { if (reader.NamespaceURI.Equals("http://www.w3.org/2000/xmlns/") || reader.NamespaceURI.Equals(XmlNs.xsi) && reader.LocalName.Equals("type")) { continue; } var propertyName = reader.LocalName; var attributeNamespace = reader.NamespaceURI; var attributeProperty = AllProperties().FirstOrDefault(p => p.Form == XmlFormEnum.Attribute && p.LocalName.Equals(propertyName) && p.NamespaceURI.Equals(attributeNamespace)); if (attributeProperty == null) { if (!Open) { throw new XdtoException($"Ошиба разбора XDTO: Получили неизвестный атрибут {propertyName}"); } var type = factory.Type(new XmlDataType("string")); attributeProperty = new XdtoProperty(null, result, XmlFormEnum.Attribute, NamespaceUri, propertyName, 1, -1, type); // TODO: lower / upper для открытого типа } var attributeValue = attributeProperty.Type.Reader.ReadXml(reader, attributeProperty.Type, factory); result.Set(attributeProperty, ValueFactory.Create(attributeValue)); } while (reader.Read()) { if (reader.NodeType.Equals(xmlElementEnd)) { // TODO: result.Validate() return(result); } if (reader.NodeType.Equals(xmlText)) { // надо найти свойство с Form=Text // оно должно быть одно var textProperty = AllProperties().FirstOrDefault((p) => p.Form == XmlFormEnum.Text); IXdtoType type; IValue textValue; if (textProperty == null) { if (!Open) { throw new XdtoException($"Ошибка разбора XDTO: Текст {reader.Value} в неположенном месте при разборе типа {this}!"); } textProperty = new XdtoProperty(null, result, XmlFormEnum.Text, NamespaceUri, "#text"); type = factory.Type(new XmlDataType("string")); textValue = ValueFactory.Create(reader.Value); } else { type = textProperty.Type; textValue = ValueFactory.Create(type.Reader.ReadXml(reader, type, factory)); } if (Sequenced) { result.Sequence().Add(textValue.AsString()); } else { result.Set(textProperty, textValue); } } else if (reader.NodeType.Equals(xmlElementStart)) { var localName = reader.LocalName; var ns = reader.NamespaceURI; var property = AllProperties().FirstOrDefault((p) => p.LocalName.Equals(localName) && p.NamespaceURI.Equals(ns) && p.Form == XmlFormEnum.Element); if (property == null) { if (!Open) { throw new XdtoException($"Ошибка разбора XDTO: Получили неизвестный элемент {localName}"); } // TODO: lower / upper для открытого типа property = new XdtoProperty(null, result, XmlFormEnum.Element, ns, localName, 1, 1); } var elementValue = factory.ReadXml(reader, property.Type); // TODO: Разбор anyType if (property.UpperBound != 1) { // TODO: проверка на null - на отсутствие/наличие списка (result.GetList(property) as XdtoList).Add(elementValue); } else { result.Set(property, elementValue); } } } throw new XdtoException("Ошибка разбора XDTO!"); }