public Place ObjectToElement(INakedObjectAdapter nakedObjectAdapter) { var nos = (IObjectSpec)nakedObjectAdapter.Spec; var element = Schema.CreateElement(XmlDocument, nos.ShortName, nos.FullName, nos.SingularName, nos.PluralName); NofMetaModel.AppendNofTitle(element, nakedObjectAdapter.TitleString()); var xsElement = Schema.CreateXsElementForNofClass(XsdDocument, element, topLevelElementWritten); // hack: every element in the XSD schema apart from first needs minimum cardinality setting. topLevelElementWritten = true; var place = new Place(nakedObjectAdapter, element); NofMetaModel.SetAttributesForClass(element, OidOrHashCode(nakedObjectAdapter)); var fields = nos.Properties; var seenFields = new List <string>(); foreach (var field in fields) { var fieldName = field.Id; // Skip field if we have seen the name already // This is a workaround for getLastActivity(). This method exists // in AbstractNakedObject, but is not (at some level) being picked up // by the dot-net reflector as a property. On the other hand it does // exist as a field in the meta model (NakedObjectSpecification). // // Now, to re-expose the LastActivity field for .Net, a deriveLastActivity() // has been added to BusinessObject. This caused another field of the // same name, ultimately breaking the XSD. if (seenFields.Contains(fieldName)) { continue; } seenFields.Add(fieldName); XNamespace ns = Schema.GetUri(); var xmlFieldElement = new XElement(ns + fieldName); XElement xsdFieldElement; var oneToOneAssociation = field as IOneToOneAssociationSpec; var oneToManyAssociation = field as IOneToManyAssociationSpec; if (field.ReturnSpec.IsParseable && oneToOneAssociation != null) { var fieldNos = field.ReturnSpec; // skip fields of type XmlValue if (fieldNos?.FullName != null && fieldNos.FullName.EndsWith("XmlValue")) { continue; } var xmlValueElement = xmlFieldElement; // more meaningful locally scoped name try { var value = oneToOneAssociation.GetNakedObject(nakedObjectAdapter); // a null value would be a programming error, but we protect // against it anyway if (value == null) { continue; } var valueNos = value.Spec; // XML NofMetaModel.SetAttributesForValue(xmlValueElement, valueNos.ShortName); var notEmpty = value.TitleString().Length > 0; if (notEmpty) { var valueStr = value.TitleString(); xmlValueElement.Add(new XText(valueStr)); } else { NofMetaModel.SetIsEmptyAttribute(xmlValueElement, true); } } catch (Exception) { logger.LogWarning($"objectToElement(NO): {DoLog("field", fieldName)}: getField() threw exception - skipping XML generation"); } // XSD xsdFieldElement = Schema.CreateXsElementForNofValue(xsElement, xmlValueElement); } else if (oneToOneAssociation != null) { var xmlReferenceElement = xmlFieldElement; // more meaningful locally scoped name try { var referencedNakedObjectAdapter = oneToOneAssociation.GetNakedObject(nakedObjectAdapter); var fullyQualifiedClassName = field.ReturnSpec.FullName; // XML NofMetaModel.SetAttributesForReference(xmlReferenceElement, Schema.Prefix, fullyQualifiedClassName); if (referencedNakedObjectAdapter != null) { NofMetaModel.AppendNofTitle(xmlReferenceElement, referencedNakedObjectAdapter.TitleString()); } else { NofMetaModel.SetIsEmptyAttribute(xmlReferenceElement, true); } } catch (Exception) { logger.LogWarning($"objectToElement(NO): {DoLog("field", fieldName)}: getAssociation() threw exception - skipping XML generation"); } // XSD xsdFieldElement = Schema.CreateXsElementForNofReference(xsElement, xmlReferenceElement, oneToOneAssociation.ReturnSpec.FullName); } else if (oneToManyAssociation != null) { var xmlCollectionElement = xmlFieldElement; // more meaningful locally scoped name try { var collection = oneToManyAssociation.GetNakedObject(nakedObjectAdapter); var facet = collection.GetTypeOfFacetFromSpec(); var referencedTypeNos = facet.GetValueSpec(collection, metamodelManager.Metamodel); var fullyQualifiedClassName = referencedTypeNos.FullName; // XML NofMetaModel.SetNofCollection(xmlCollectionElement, Schema.Prefix, fullyQualifiedClassName, collection, nakedObjectManager); } catch (Exception) { logger.LogWarning($"objectToElement(NO): {DoLog("field", fieldName)}: get(obj) threw exception - skipping XML generation"); } // XSD xsdFieldElement = Schema.CreateXsElementForNofCollection(xsElement, xmlCollectionElement, oneToManyAssociation.ReturnSpec.FullName); } else { continue; } if (xsdFieldElement != null) { xmlFieldElement.AddAnnotation(xsdFieldElement); } // XML MergeTree(element, xmlFieldElement); // XSD if (xsdFieldElement != null) { Schema.AddFieldXsElement(xsElement, xsdFieldElement); } } return(place); }