public static IEnumerable<InfoPathFeature> ParseFeature(XDocument document) { IEnumerable<XElement> allElements = document.Descendants(xslNamespace + xslAttribute); foreach (XElement element in allElements) { XAttribute name = element.Attribute(nameAttribute); // these are the html attributes that we try to set. // specifically for conditional hide we have to look under a style for an xsl:when with .Text() contains "DISPLAY: none" if (name.Value.Equals(contentEditable)) { FormattingRule rule = new FormattingRule(); rule.FormatType = "Readonly"; yield return rule; } else if (name.Value.Equals(style)) { Utilities.BucketCounter counter = new Utilities.BucketCounter(); FormattingRule rule = new FormattingRule(); rule.FormatType = "Style"; // now let's count all the things we're affecting. // Overloading BucketCounter to filter the noise of multiple touches to same style foreach (XElement xslWhen in element.Descendants(xslNamespace + when)) { string[] styles = xslWhen.Value.Split(new char[] { ';' }); foreach (string s in styles) { if (s.Trim().StartsWith("caption:")) continue; string affectedStyle = s.Split(':')[0].Trim().ToUpper(); counter.IncrementKey(affectedStyle); } } StringBuilder sb = new StringBuilder(); foreach (KeyValuePair<string, int> kvp in counter.Buckets) { sb.Append(kvp.Key).Append(" "); } rule.SubDetails = sb.ToString().Trim(); yield return rule; } } // nothing left yield break; }