/// <summary> /// Converts the JSON into the XML equivalent. /// </summary> private static void ConvertJson(ConfigurationEntity entity, XElement xml, JObject jo) { foreach (var jp in jo.Children().OfType <JProperty>()) { if (jp.Value.Type == JTokenType.Array) { var ci = GetConfigInfo(jp.Name); if (ci.entity == ConfigurationEntity.None) { continue; } var ja = jp.Value as JArray; foreach (var ji in ja !) { if (ji.Type == JTokenType.Object) { var xe = new XElement(ci.name); ConvertJson(ci.entity, xe, (JObject)ji); xml.Add(xe); } } } else { xml.Add(new XAttribute(XmlJsonRename.GetXmlName(entity, jp.Name), jp.Value)); } } }
/// <summary> /// Writes the schema for the object. /// </summary> private static void WriteObject(Type type, XNamespace ns, XElement xe, bool isRoot) { var csa = type.GetCustomAttribute <ClassSchemaAttribute>(); if (csa == null) { throw new InvalidOperationException($"Type '{type.Name}' does not have a required ClassSchemaAttribute."); } if (!Enum.TryParse <ConfigurationEntity>(csa.Name, out var ce)) { ce = ConfigurationEntity.CodeGen; } var xml = new XElement(ns + "element"); xml.Add(new XAttribute("name", csa.Name)); if (!isRoot) { xml.Add(new XAttribute("minOccurs", "0")); xml.Add(new XAttribute("maxOccurs", "unbounded")); } xml.Add(new XElement(ns + "annotation", new XElement(ns + "documentation", csa.Title))); var xct = new XElement(ns + "complexType"); // Add sub-collections within xs:sequence element. var hasSeq = false; var xs = new XElement(ns + "sequence"); foreach (var pi in type.GetProperties()) { var pcsa = pi.GetCustomAttribute <PropertyCollectionSchemaAttribute>(); if (pcsa == null) { continue; } WriteObject(ComplexTypeReflector.GetItemType(pi.PropertyType), ns, xs, false); hasSeq = true; } if (hasSeq) { xct.Add(xs); } // Add properties as xs:attribute's. foreach (var pi in type.GetProperties()) { var jpa = pi.GetCustomAttribute <JsonPropertyAttribute>(); if (jpa == null) { continue; } var psa = pi.GetCustomAttribute <PropertySchemaAttribute>(); if (psa == null) { continue; } var name = jpa.PropertyName ?? Beef.CodeGen.CodeGenerator.ToCamelCase(pi.Name) !; var xp = new XElement(ns + "attribute", new XAttribute("name", XmlJsonRename.GetXmlName(ce, name)), new XAttribute("use", psa.IsMandatory ? "required" : "optional")); xp.Add(new XElement(ns + "annotation", new XElement(ns + "documentation", GetDocumentation(name, psa)))); if (psa.Options == null) { xp.Add(new XAttribute("type", GetXmlType(pi))); } else { var xr = new XElement(ns + "restriction", new XAttribute("base", GetXmlType(pi))); foreach (var opt in psa.Options) { xr.Add(new XElement(ns + "enumeration", new XAttribute("value", opt))); } xp.Add(new XElement(ns + "simpleType", xr)); } xct.Add(xp); } // Add this type into the overall document. xml.Add(xct); xe.Add(xml); }