static void GenerateUXMLRecursive( VisualTreeAsset vta, string vtaPath, VisualElementAsset root, Dictionary <int, List <VisualElementAsset> > idToChildren, StringBuilder stringBuilder, int depth, bool writingToFile) { Indent(stringBuilder, depth); stringBuilder.Append(BuilderConstants.UxmlOpenTagSymbol); AppendElementTypeName(root, stringBuilder); // Add all non-style attributes. AppendElementNonStyleAttributes(root, stringBuilder, writingToFile); // Add style classes to class attribute. if (root.classes != null && root.classes.Length > 0) { stringBuilder.Append(" class=\""); for (int i = 0; i < root.classes.Length; i++) { if (i > 0) { stringBuilder.Append(" "); } stringBuilder.Append(root.classes[i]); } stringBuilder.Append("\""); } // Add inline StyleSheet attribute. if (root.ruleIndex != -1) { if (vta.inlineSheet == null) { Debug.LogWarning("VisualElementAsset has a RuleIndex but no inlineStyleSheet"); } else { StyleRule r = vta.inlineSheet.rules[root.ruleIndex]; if (r.properties != null && r.properties.Length > 0) { var ruleBuilder = new StringBuilder(); var exportOptions = new UssExportOptions(); exportOptions.propertyIndent = string.Empty; StyleSheetToUss.ToUssString(vta.inlineSheet, exportOptions, r, ruleBuilder); var ruleStr = ruleBuilder.ToString(); // Need to remove newlines here before we give it to // AppendElementAttribute() so we don't add " " everywhere. ruleStr = ruleStr.Replace("\n", " "); ruleStr = ruleStr.Replace("\r", ""); ruleStr = ruleStr.Trim(); AppendElementAttribute("style", ruleStr, stringBuilder); } } } // If we have no children, avoid adding the full end tag and just end the open tag. bool hasChildTags = false; // Add special children. var styleSheets = root.GetStyleSheets(); var styleSheetPaths = root.GetStyleSheetPaths(); if (styleSheetPaths != null && styleSheetPaths.Count > 0) { Assert.IsNotNull(styleSheets); Assert.AreEqual(styleSheetPaths.Count, styleSheets.Count); bool newLineAdded = false; for (var i = 0; i < styleSheetPaths.Count; ++i) { var styleSheet = styleSheets[i]; var styleSheetPath = styleSheetPaths[i]; ProcessStyleSheetPath( vtaPath, styleSheet, styleSheetPath, stringBuilder, depth, ref newLineAdded, ref hasChildTags); } } var templateAsset = root as TemplateAsset; if (templateAsset != null && templateAsset.attributeOverrides != null && templateAsset.attributeOverrides.Count > 0) { if (!hasChildTags) { stringBuilder.Append(BuilderConstants.UxmlCloseTagSymbol); stringBuilder.Append(BuilderConstants.newlineCharFromEditorSettings); } var overridesMap = new Dictionary <string, List <TemplateAsset.AttributeOverride> >(); foreach (var attributeOverride in templateAsset.attributeOverrides) { if (!overridesMap.ContainsKey(attributeOverride.m_ElementName)) { overridesMap.Add(attributeOverride.m_ElementName, new List <TemplateAsset.AttributeOverride>()); } overridesMap[attributeOverride.m_ElementName].Add(attributeOverride); } foreach (var attributeOverridePair in overridesMap) { var elementName = attributeOverridePair.Key; var overrides = attributeOverridePair.Value; Indent(stringBuilder, depth + 1); stringBuilder.Append(BuilderConstants.UxmlOpenTagSymbol + "AttributeOverrides"); AppendElementAttribute("element-name", elementName, stringBuilder); foreach (var attributeOverride in overrides) { AppendElementAttribute(attributeOverride.m_AttributeName, attributeOverride.m_Value, stringBuilder); } stringBuilder.Append(" " + BuilderConstants.UxmlCloseTagSymbol); stringBuilder.Append(BuilderConstants.newlineCharFromEditorSettings); } hasChildTags = true; } // Iterate through child elements. List <VisualElementAsset> children; if (idToChildren != null && idToChildren.TryGetValue(root.id, out children) && children.Count > 0) { if (!hasChildTags) { stringBuilder.Append(BuilderConstants.UxmlCloseTagSymbol); stringBuilder.Append(BuilderConstants.newlineCharFromEditorSettings); } children.Sort(VisualTreeAssetUtilities.CompareForOrder); foreach (var childVea in children) { GenerateUXMLRecursive( vta, vtaPath, childVea, idToChildren, stringBuilder, depth + 1, writingToFile); } hasChildTags = true; } // Iterate through Uxml Objects var entry = vta.GetUxmlObjectEntry(root.id); if (entry.uxmlObjectAssets != null && entry.uxmlObjectAssets.Count > 0) { if (!hasChildTags) { stringBuilder.Append(BuilderConstants.UxmlCloseTagSymbol); stringBuilder.Append(BuilderConstants.newlineCharFromEditorSettings); } foreach (var childVea in entry.uxmlObjectAssets) { GenerateUXMLRecursive( vta, vtaPath, childVea, idToChildren, stringBuilder, depth + 1, writingToFile); } hasChildTags = true; } if (hasChildTags) { Indent(stringBuilder, depth); stringBuilder.Append(BuilderConstants.UxmlOpenTagSymbol + "/"); AppendElementTypeName(root, stringBuilder); stringBuilder.Append(BuilderConstants.UxmlCloseTagSymbol); stringBuilder.Append(BuilderConstants.newlineCharFromEditorSettings); } else { stringBuilder.Append(" " + BuilderConstants.UxmlEndTagSymbol); stringBuilder.Append(BuilderConstants.newlineCharFromEditorSettings); } }