private void ParseStartElements(XmlTextReader reader, Dictionary<string, ClassInfo> table, ParentInfo parent, XmlNamespaceManager nps, string className) { if (stack.Count != 0) { ////Get the parent parent = stack.Peek(); ////Get the child element from inside the parent if (parent.ChildCount.ContainsKey(className)) { ////increment the Occurrence of the child element inside the parent int childCount = parent.ChildCount[className]; parent.ChildCount[className] = ++childCount; } else { ////if child does not exist in the parent add it with Occurrence = 1 parent.ChildCount.Add(className, 1); } } if (!reader.IsEmptyElement) { ////If its not an empty element push it in the stack which ////contains all parent elements stack.Push(new ParentInfo()); } ClassInfo classInfo; if (!table.TryGetValue(className, out classInfo)) { ////Create a ClassInfo every time we hit an element and it is not already ////contained in the global table. classInfo = new ClassInfo(className); table.Add(className, classInfo); } if (reader.LocalName != reader.Name) { string lookupName = reader.Prefix == "xmlns" ? reader.LocalName : reader.Prefix; classInfo.Namespace = nps.LookupNamespace(lookupName); } ////Add any new attributes that are not already defined in the classInfo.... for (int index = 0; index < reader.AttributeCount; index++) { reader.MoveToAttribute(index); string localName = reader.LocalName; if (!classInfo.Properties.ContainsKey(localName) && (!reader.Name.StartsWith("xmlns"))) { PropertyInfo propertyInfo = new PropertyInfo(localName, true); classInfo.Properties[propertyInfo.Name] = propertyInfo; } } }
/// <summary> /// Generates the code DOM tree. /// </summary> /// <param name="codeXml">The code XML.</param> /// <param name="url">The URL.</param> /// <param name="namespaceName">Name of the namespace.</param> /// <param name="classNamePrefix">The class name prefix.</param> /// <param name="outputCodeCompileUnit">The output code compile unit.</param> /// <param name="useBaseClass">if set to <c>true</c> [use base class].</param> public static void GenerateCodeDomTree( string codeXml, string url, string namespaceName, string classNamePrefix, CodeCompileUnit outputCodeCompileUnit, bool useBaseClass) { if (string.IsNullOrEmpty(codeXml)) { throw new ArgumentException(string.Format(Resources.RssToolkit.Culture, Resources.RssToolkit.ArgmentException, "codeXml")); } if (namespaceName == null) { throw new ArgumentNullException("namespaceName"); } if (string.IsNullOrEmpty(classNamePrefix)) { throw new ArgumentException(string.Format(Resources.RssToolkit.Culture, Resources.RssToolkit.ArgmentException, "classNamePrefix")); } if (outputCodeCompileUnit == null) { throw new ArgumentNullException("outputCodeCompileUnit"); } if (outputCodeCompileUnit.Namespaces == null) { throw new ArgumentNullException("outputCodeCompileUnit.Namespaces"); } RssCodeTreeGenerator codeTree = new RssCodeTreeGenerator(); Dictionary <string, ClassInfo> classDictionary = codeTree.ConvertToDictionary(codeXml); // generate namespace CodeNamespace generatedNamespace = new CodeNamespace(namespaceName); generatedNamespace.Imports.Add(new CodeNamespaceImport("System")); generatedNamespace.Imports.Add(new CodeNamespaceImport("System.Xml")); generatedNamespace.Imports.Add(new CodeNamespaceImport("System.Xml.Serialization")); generatedNamespace.Imports.Add(new CodeNamespaceImport("System.Collections.Generic")); generatedNamespace.Imports.Add(new CodeNamespaceImport(NamespaceConstant)); foreach (string classKey in classDictionary.Keys) { ClassInfo classInfo = classDictionary[classKey]; if (classInfo.Properties.Count > 0) { string className = classNamePrefix + CodeNameFromRssName(classInfo.Name); CodeTypeDeclaration itemType = new CodeTypeDeclaration(className); if (classInfo.Name.Equals(RssConstant, StringComparison.OrdinalIgnoreCase)) { itemType.CustomAttributes.Add(new CodeAttributeDeclaration("System.Serializable")); itemType.CustomAttributes.Add(new CodeAttributeDeclaration("System.Xml.Serialization.XmlRoot", new CodeAttributeArgument(new CodePrimitiveExpression("rss")))); if (useBaseClass) { itemType.BaseTypes.Add(new CodeTypeReference(RssNamespaceConstant)); } if (!string.IsNullOrEmpty(url)) { string itemTypeName = classNamePrefix + "Item"; //// LoadRss (and LoadRssItems) method GenerateLoad(itemType, url); GenerateLoadRssByUrl(itemType); GenerateLoadRssByXmlTextReader(itemType); GenerateLoadRssByXml(itemType); GenerateLoadRssItems(itemType, itemTypeName); } GenerateToXml(itemType); GenerateToDataSet(itemType); } if (!NamespaceContainsType(generatedNamespace, itemType.Name)) { generatedNamespace.Types.Add(itemType); } foreach (string propertyKey in classInfo.Properties.Keys) { PropertyInfo property = classInfo.Properties[propertyKey]; string propertyName = classNamePrefix + CodeNameFromRssName(property.Name); AddCodeProperty( property.Name, property.IsAttribute ? XmlNodeType.Attribute : XmlNodeType.Element, (classDictionary.ContainsKey(property.Name) && classDictionary[property.Name].Properties.Count > 0) ? new CodeTypeReference(propertyName) : new CodeTypeReference("System.String"), itemType, property.Occurrences > 1 ? true : false, (classDictionary.ContainsKey(property.Name) ? classDictionary[property.Name].Namespace : string.Empty)); } if (classInfo.IsText) { AddCodeProperty("Text", XmlNodeType.Text, new CodeTypeReference("System.String"), itemType, false, string.Empty); } } } if (useBaseClass) { // generate http handler base class string handlerTypeName = classNamePrefix + "HttpHandlerBase"; CodeTypeDeclaration handlerType = new CodeTypeDeclaration(handlerTypeName); handlerType.BaseTypes.Add(new CodeTypeReference(HttpHandlerNamespaceConstant, new CodeTypeReference[1] { new CodeTypeReference(classNamePrefix + RssConstant) })); generatedNamespace.Types.Add(handlerType); } // add the generated namespace to the code compile unit outputCodeCompileUnit.Namespaces.Add(generatedNamespace); }