private static DomObject CreateElement(XmlReader reader, DomMetaElement metaElement) { DomComplexType type = metaElement.Type; // Check for xsi:type attribute, indicating a derived type string typeName = reader.GetAttribute("xsi:type"); if (typeName != null) { // check for qualified type name string prefix = string.Empty; int index = typeName.IndexOf(':'); if (index >= 0) { prefix = typeName.Substring(0, index); index++; typeName = typeName.Substring(index, typeName.Length - index); } string ns = reader.LookupNamespace(prefix); XmlQualifiedName qualifiedName = new XmlQualifiedName(typeName, ns); type = DomSchemaRegistry.GetComplexType(qualifiedName); if (type == null) { throw new InvalidOperationException("Unknown derived type"); } } return(new DomObject(type)); }
private static void GetAllAnnotations(DomComplexType complexType, ref List <XmlNode> lstAnnotations) { lstAnnotations.AddRange(complexType.Annotation); if (complexType.BaseType != null) { GetAllAnnotations(complexType.BaseType, ref lstAnnotations); } }
/// <summary> /// Write element /// </summary> /// <param name="element"></param> /// <param name="writer"></param> /// <param name="schema"></param> /// <param name="bTemp"></param> protected void WriteElement(DomObject element, XmlWriter writer, DomSchema schema, bool bTemp) { // Test if the element should be saved or not if (!bTemp && !element.CanCreateInterface <ISledProjectFilesSaveableType>()) { return; } string elemNs = element.MetaElement.QualifiedName.Namespace; string elemPrefix; // Is this the root DomObject? if (schema != null) { elemPrefix = schema.GetPrefix(elemNs) ?? GeneratePrefix(elemNs); writer.WriteStartElement(elemPrefix, element.MetaElement.Name, elemNs); // Define the xsi namespace writer.WriteAttributeString("xmlns", "xsi", null, XmlSchema.InstanceNamespace); // Define schema namespaces foreach (XmlQualifiedName name in schema.Namespaces) { if (name.Name != elemPrefix) // don't redefine the element namespace { writer.WriteAttributeString("xmlns", name.Name, null, name.Namespace); } } } else { // Not the root, so all schema namespaces have been defined elemPrefix = writer.LookupPrefix(elemNs) ?? GeneratePrefix(elemNs); writer.WriteStartElement(elemPrefix, element.MetaElement.Name, elemNs); } // Write type name if this is a polymorphic type DomComplexType elementType = element.Type; if (element.MetaElement.Type != elementType) { string typeName = elementType.Name.Name; string typeNs = elementType.Name.Namespace; string typePrefix = writer.LookupPrefix(typeNs); if (typePrefix == null) { typePrefix = GeneratePrefix(typeNs); writer.WriteAttributeString("xmlns", typePrefix, null, typeNs); } if (typePrefix != string.Empty) { typeName = typePrefix + ":" + typeName; } writer.WriteAttributeString("xsi", "type", XmlSchema.InstanceNamespace, typeName); } // When writing project file we build a list of attributes to NOT save List <string> lstAttrsDontSave = new List <string>(); // Do some stuff if writing project file if (!bTemp) { // Get all annotations (including base type annotations [and their base type annotations etc.]) List <XmlNode> lstAnnotations = new List <XmlNode>(); GetAllAnnotations(element.Type, ref lstAnnotations); // Go through pulling out which attributes to not save based on the annotation foreach (XmlNode annotation in lstAnnotations) { // Do something if it's a "dont save" annotation! if (string.Compare(annotation.Name, DontSaveAnnotation, true) == 0) { XmlNode node = annotation.Attributes.GetNamedItem("name"); if (node != null) { string szAttribute = node.Value; if (!lstAttrsDontSave.Contains(szAttribute)) { lstAttrsDontSave.Add(szAttribute); } } } } } // Write normal attributes foreach (DomMetaAttribute attribute in elementType.Attributes) { // Do some stuff if writing project file if (!bTemp && (lstAttrsDontSave.Count > 0) && !string.IsNullOrEmpty(attribute.Name)) { if (lstAttrsDontSave.Contains(attribute.Name)) { continue; } } object value = element.GetAttribute(attribute); if (attribute.Required) { if (value == null) { throw new InvalidOperationException("missing attribute"); } writer.WriteAttributeString(attribute.Name, attribute.Type.Convert(value)); } else if (value != null && value != attribute.Type.GetDefault()) { writer.WriteAttributeString(attribute.Name, attribute.Type.Convert(value)); } } // Write element value if (element.Value != null && element.Value != elementType.ValueType.GetDefault()) { writer.WriteString(elementType.ValueType.Convert(element.Value)); } // write child elements foreach (DomMetaElement elem in elementType.Children) { foreach (DomObject child in element.GetChildren(elem.Name)) { WriteElement(child, writer, null, bTemp); } } writer.WriteEndElement(); }
/// <summary> /// Read element /// </summary> /// <param name="domObject"></param> /// <param name="reader"></param> protected void ReadElement(DomObject domObject, XmlReader reader) { DomComplexType type = domObject.Type; // Read attributes int required = type.RequiredAttributes; while (reader.MoveToNextAttribute()) { if (reader.Prefix == string.Empty || reader.LookupNamespace(reader.Prefix) == type.Name.Namespace) { DomMetaAttribute metaAttribute = type.GetAttribute(reader.LocalName); if (metaAttribute != null) { object value = metaAttribute.Type.Convert(reader.Value); domObject.SetAttribute(metaAttribute.Name, value); if (metaAttribute.Required) { required--; } } } } if (required != 0) { throw new InvalidOperationException("Missing required attribute"); } reader.MoveToElement(); if (!reader.IsEmptyElement) { // Read child elements while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { // look up metadata for this element DomMetaElement metaElement = type.GetChild(reader.LocalName); if (metaElement != null) { DomObject child = CreateElement(reader, metaElement); ReadElement(child, reader); // At this point, child is a fully populated sub-tree domObject.AddChild(metaElement, child); } else { reader.Skip(); } } else if (reader.NodeType == XmlNodeType.Text) { if (type.ValueType != null) { domObject.Value = type.ValueType.Convert(reader.Value); } } else if (reader.NodeType == XmlNodeType.EndElement) { break; } } } reader.MoveToContent(); }