public Place ObjectToElement(INakedObjectAdapter nakedObjectAdapter) { var nos = (IObjectSpec)nakedObjectAdapter.Spec; XElement element = Schema.CreateElement(XmlDocument, nos.ShortName, nos.FullName, nos.SingularName, nos.PluralName); NofMetaModel.AppendNofTitle(element, nakedObjectAdapter.TitleString()); XElement 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)); IAssociationSpec[] fields = nos.Properties; var seenFields = new List <string>(); foreach (IAssociationSpec field in fields) { string 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 ofthe // 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) { IObjectSpec fieldNos = field.ReturnSpec; // skip fields of type XmlValue if (fieldNos?.FullName != null && fieldNos.FullName.EndsWith("XmlValue")) { continue; } XElement xmlValueElement = xmlFieldElement; // more meaningful locally scoped name try { INakedObjectAdapter value = oneToOneAssociation.GetNakedObject(nakedObjectAdapter); // a null value would be a programming error, but we protect // against it anyway if (value == null) { continue; } ITypeSpec valueNos = value.Spec; // XML NofMetaModel.SetAttributesForValue(xmlValueElement, valueNos.ShortName); bool notEmpty = value.TitleString().Length > 0; if (notEmpty) { string valueStr = value.TitleString(); xmlValueElement.Add(new XText(valueStr)); } else { NofMetaModel.SetIsEmptyAttribute(xmlValueElement, true); } } catch (Exception) { Log.Warn("objectToElement(NO): " + DoLog("field", fieldName) + ": getField() threw exception - skipping XML generation"); } // XSD xsdFieldElement = Schema.CreateXsElementForNofValue(xsElement, xmlValueElement); } else if (oneToOneAssociation != null) { XElement xmlReferenceElement = xmlFieldElement; // more meaningful locally scoped name try { INakedObjectAdapter referencedNakedObjectAdapter = oneToOneAssociation.GetNakedObject(nakedObjectAdapter); string 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) { Log.Warn("objectToElement(NO): " + DoLog("field", fieldName) + ": getAssociation() threw exception - skipping XML generation"); } // XSD xsdFieldElement = Schema.CreateXsElementForNofReference(xsElement, xmlReferenceElement, oneToOneAssociation.ReturnSpec.FullName); } else if (oneToManyAssociation != null) { XElement xmlCollectionElement = xmlFieldElement; // more meaningful locally scoped name try { INakedObjectAdapter collection = oneToManyAssociation.GetNakedObject(nakedObjectAdapter); ITypeOfFacet facet = collection.GetTypeOfFacetFromSpec(); IObjectSpecImmutable referencedTypeNos = facet.GetValueSpec(collection, metamodelManager.Metamodel); string fullyQualifiedClassName = referencedTypeNos.FullName; // XML NofMetaModel.SetNofCollection(xmlCollectionElement, Schema.Prefix, fullyQualifiedClassName, collection, nakedObjectManager); } catch (Exception) { Log.Warn("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); }