internal XdtoDataObject(XdtoObjectType type, XdtoDataObject owner, XdtoProperty property) { _type = type; _owner = owner; _owningProperty = property; _sequence = new XdtoSequence(this, true); FillPropertiesFromType(); }
internal XdtoProperty(IXdtoType ownerType, XdtoDataObject ownerObject, XmlFormEnum form, string namespaceUri, string localName, int lowerBound = 1, int upperBound = 1, IXdtoType type = null) { NamespaceURI = namespaceUri; LocalName = localName; Name = localName; Form = form; _ownerType = ownerType; OwnerObject = ownerObject; LowerBound = lowerBound; UpperBound = upperBound; _type = type; }
private void WriteXdtoObject(XmlWriterImpl xmlWriter, XdtoDataObject obj) { obj.Validate(); if (obj.Type().Sequenced) { WriteXdtoSequence(xmlWriter, obj.Sequence()); return; } foreach (var property in obj.Properties()) { var typeAssignment = XmlTypeAssignmentEnum.Explicit; if (property.UpperBound != 1) { // это список var value = obj.GetList(property) as XdtoList; foreach (var listElement in value) { WriteXml(xmlWriter, listElement, property.LocalName, property.NamespaceURI, typeAssignment, property.Form); } } else { var value = obj.GetXdto(property); if (value != null || property.Nillable) { WriteXml(xmlWriter, value, property.LocalName, property.NamespaceURI, typeAssignment, property.Form); } } } }
internal XdtoList(XdtoDataObject owner, XdtoProperty owningProperty) { Owner = owner; OwningProperty = owningProperty; }
internal XdtoSequence(XdtoDataObject owner, bool isMixed) { Owner = owner; _isMixed = isMixed; }
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!"); }