/*************************************************************************** Copyright (c) Microsoft Corporation 2011. This code is licensed using the Microsoft Public License (Ms-PL). The text of the license can be found here: http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx ***************************************************************************/ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Xml.Linq; namespace OpenXmlPowerTools { /// /// Provides access to content style operations /// public class ContentStyleAccessor { private static XNamespace ns; private const string newStyleNameSuffix = "_1"; static ContentStyleAccessor() { ns = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"; } /// /// Gets the tree representing all style hierarchy for a given style /// /// Name of style /// Styles library /// Style tree private Collection GetStyleHierarchy(string styleName, string stylesFile) { Collection stylesCollection = new Collection(); XDocument xml = new XDocument(); xml = XDocument.Load(stylesFile); GetStyleDefinition(styleName, xml, stylesCollection); return stylesCollection; } /// /// Gets the style definition for the document /// /// Style name /// Style library /// Styles public void GetStyleDefinition(string styleName, XDocument xmlStyleDefinitions, Collection stylesCollection) { XName style = ns + "style"; XName styleId = ns + "styleId"; // create a copy of the xmlstyleDefinition variable so the // original xml don't be altered XElement actualStyle = new XElement( xmlStyleDefinitions .Descendants() .Where( tag => (tag.Name == style) && (tag.Attribute(styleId).Value == styleName) ) .ToList() .FirstOrDefault() ); if (actualStyle != null) { // look in the stylesCollection if the style has already been added IEnumerable insertedStyles = stylesCollection.Where ( tag => (tag.Name == style) && (tag.Attribute(styleId).Value == styleName) ); // if the style has not been inserted if (!(insertedStyles.Count() > 0)) { stylesCollection.Add(actualStyle); GetStyleDefinition(getLinkStyleId(actualStyle), xmlStyleDefinitions, stylesCollection); GetStyleDefinition(getNextStyleId(actualStyle), xmlStyleDefinitions, stylesCollection); GetStyleDefinition(getBasedOnStyleId(actualStyle), xmlStyleDefinitions, stylesCollection); } // change the name of the style, so there would be no conflict // with the original styles definition actualStyle.Attribute(styleId).Value = actualStyle.Attribute(styleId).Value + newStyleNameSuffix; } } /// /// Gets the name of the linked style associated to the given style /// /// Style to find link /// Linked style name public string getLinkStyleId(XElement xmlStyle) { XName val = ns + "val"; string linkStyleId = ""; XElement linkStyle = xmlStyle.Descendants(ns + "link").FirstOrDefault(); if (linkStyle != null) { linkStyleId = linkStyle.Attribute(val).Value; // change the name of the attribute, because the new added style is being renamed linkStyle.Attribute(val).Value = linkStyle.Attribute(val).Value + newStyleNameSuffix; } return linkStyleId; } /// /// Gets the name of the style tagged as 'next' associated to the given style /// /// Style to find 'next' element /// Name of style tagged as 'next public string getNextStyleId(XElement xmlStyle) { XName val = ns + "val"; string nextStyleId = ""; XElement nextStyle = xmlStyle.Descendants(ns + "next").FirstOrDefault(); if (nextStyle != null) { nextStyleId = nextStyle.Attribute(val).Value; // change the name of the attribute, because the new added style is being renamed nextStyle.Attribute(val).Value = nextStyle.Attribute(val).Value + newStyleNameSuffix; } return nextStyleId; } /// /// Get the name of the style tagged as 'basedOn' associated to the given style /// /// Style to find 'basedOn' element /// Name of style tagged as 'basedOn' public string getBasedOnStyleId(XElement xmlStyle) { XName val = ns + "val"; string basedOnStyleId = ""; XElement basedOnStyle = xmlStyle.Descendants(ns + "basedOn").FirstOrDefault(); if (basedOnStyle != null) { basedOnStyleId = basedOnStyle.Attribute(val).Value; // change the name of the attribute, because the new added style is being renamed basedOnStyle.Attribute(val).Value = basedOnStyle.Attribute(val).Value + newStyleNameSuffix; } return basedOnStyleId; } } }