Exemple #1
0
        // the work of the component

        public override void Apply(XmlDocument document, string key)
        {
            // adjust the context
            context["key"] = key;

            // evaluate the condition
            XPathExpression xpath_local = xpath.Clone();

            xpath_local.SetContext(context);

            Object result = document.CreateNavigator().Evaluate(xpath_local);

            // try to intrepret the result as a node set
            XPathNodeIterator result_node_iterator = result as XPathNodeIterator;

            if (result_node_iterator != null)
            {
                XPathNavigator[] result_nodes = BuildComponentUtilities.ConvertNodeIteratorToArray(result_node_iterator);
                //Console.WriteLine("{0} node-set result", result_nodes.Length);
                // if it is, apply the child components to each node value
                foreach (XPathNavigator result_node in result_nodes)
                {
                    // Console.WriteLine(result_node.Value);
                    ApplyComponents(document, result_node.Value);
                }
            }
            else
            {
                //Console.WriteLine("non-node-set result");
                // if it isn't, apply the child components to the string value of the result
                ApplyComponents(document, result.ToString());
            }
        }
        public override void Apply(XmlDocument document, string key)
        {
            // Run through all conceptual nodes, make sure the target is a valid GUID, attempt to resolve the target
            // to a link using one of the TargetSet definitions, and then replace the node with the result. Errors
            // will be dealt with as follows: 1) bad target (GUID) -> output invalidLinkFormat; 2) broken link (cannot
            // resolve target or the URL is empty) -> output brokenLinkFormat; 3) missing text -> just delete the node
            // and don't output anything (presumably there's no point in creating a link that nobody can see). In all
            // three cases we'll log the problem as a warning.
            string docBaseUrl = baseUrl == null ? null : BuildComponentUtilities.EvalXPathExpr(document, baseUrl, "key", key);

            XPathNavigator[] linkNodes = BuildComponentUtilities.ConvertNodeIteratorToArray(document.CreateNavigator().Select(conceptualLinks));
            foreach (XPathNavigator node in linkNodes)
            {
                string targetGuid = node.GetAttribute("target", String.Empty);
                string url        = targetGuid;
                string text       = node.ToString();
                string format;
                if (validGuid.IsMatch(url))
                {
                    format = brokenLinkFormat;
                    Target t = targetSets.Lookup(targetGuid);
                    if (t == null)
                    {
                        WriteMessage(MessageLevel.Warn, String.Format("Conceptual link not found in target sets; target={0}", targetGuid));
                    }
                    else
                    {
                        if (!String.IsNullOrEmpty(t.Url))
                        {
                            format = t.TargetSet.Format;
                            url    = (docBaseUrl != null && t.TargetSet.RelativeUrl) ?
                                     BuildComponentUtilities.GetRelativePath(t.Url, docBaseUrl) : t.Url;
                            if (!String.IsNullOrEmpty(t.Text))
                            {
                                text = t.Text;
                            }
                        }
                        else
                        {
                            WriteMessage(MessageLevel.Warn, String.Format("Conceptual link found in target set, but meta data does not specify a url; target={0}", targetGuid));
                        }
                    }
                }
                else
                {
                    format = invalidLinkFormat;
                }

                if (String.IsNullOrEmpty(text))
                {
                    node.DeleteSelf();
                    WriteMessage(MessageLevel.Warn, String.Format("Skipping conceptual link without text; target={0}", url));
                }
                else
                {
                    node.OuterXml = String.Format(format, url, text);
                }
            }
        }
        /// <summary>
        /// This is used to create a <see cref="TargetDictionary"/> used to store reference link targets
        /// </summary>
        /// <param name="configuration">The configuration element for the target dictionary</param>
        /// <returns>A default <see cref="InMemoryTargetDictionary"/> instance containing the reference link
        /// targets</returns>
        /// <remarks>This can be overridden in derived classes to provide persistent caches with backing stores
        /// other than the default <see cref="Dictionary{TKey, TValue}"/></remarks>.
        public virtual TargetDictionary CreateTargetDictionary(XPathNavigator configuration)
        {
            TargetDictionary d = null;

            try
            {
                d = new InMemoryTargetDictionary(this, configuration);
            }
            catch (Exception ex)
            {
                base.WriteMessage(MessageLevel.Error, BuildComponentUtilities.GetExceptionMessage(ex));
            }

            return(d);
        }
Exemple #4
0
        public override void Apply(XmlDocument document, string key)
        {
            // set the evaluation context
            context["key"] = key;

            XPathExpression path_xpath = path_expression.Clone();

            path_xpath.SetContext(context);

            // evaluate the path
            string path = document.CreateNavigator().Evaluate(path_xpath).ToString();
            string file = Path.GetFileName(path);

            string fileLinkPath = Path.Combine(linkPath, file);

            if (basePath != null)
            {
                path = Path.Combine(basePath, path);
            }


            // *SECURIY* The path name may be derived from user entered meta data in Doc Studio and as such
            // it is not trustworthy. To pass, the path must be inside the directory tree base_directory
            // (which is the current directory if a path is not specified).

            // This test is causing problems

            /*
             * string absoluteBasePath = (basePath == null) ? Directory.GetCurrentDirectory() : Path.GetFullPath(basePath);
             * string targetPath = Path.GetDirectoryName(path);
             * if (!targetPath.StartsWith(absoluteBasePath, StringComparison.CurrentCultureIgnoreCase)) {
             *  WriteMessage(MessageLevel.Error, string.Format("Cannot save document outside of base directory: {0}", targetPath));
             *  return;
             * }
             */
            string targetDirectory = Path.GetDirectoryName(path);

            if (!Directory.Exists(targetDirectory))
            {
                Directory.CreateDirectory(targetDirectory);
            }

            // save the document
            // select_expression determines which nodes get saved. If there is no select_expression
            // we simply save the root node as before. If there is a select_expression, we evaluate the
            // xpath expression and save the resulting node set. The select expression also enables the
            // "literal-text" processing instruction, which outputs its content as unescaped text.
            if (select_expression == null)
            {
                XmlNode doctype = document.DocumentType;
                try {
                    //Console.WriteLine("path = '{0}'", path);
                    //document.Save(path);

                    using (XmlWriter writer = XmlWriter.Create(path, settings)) {
                        document.Save(writer);
                    }
                } catch (IOException e) {
                    WriteMessage(MessageLevel.Error, String.Format("An access error occured while attempting to save to the file '{0}'. The error message is: {1}", path, BuildComponentUtilities.GetExceptionMessage(e)));
                } catch (XmlException e) {
                    WriteMessage(MessageLevel.Error, String.Format("Invalid XML was written to the output file '{0}'. The error message is: '{1}'", path, BuildComponentUtilities.GetExceptionMessage(e)));
                }

                // Get the relative html path for HXF generation.
                int    index    = fileLinkPath.IndexOf('/');
                string htmlPath = fileLinkPath.Substring(index + 1, fileLinkPath.Length - (index + 1));

                FileCreatedEventArgs fe = new FileCreatedEventArgs(htmlPath, Path.GetDirectoryName(targetDirectory));
                OnComponentEvent(fe);
            }
            else
            {
                // IMPLEMENTATION NOTE: The separate StreamWriter is used to maintain XML indenting.
                // Without it the XmlWriter won't honor our indent settings after plain text nodes have been
                // written.
                settings.ConformanceLevel = ConformanceLevel.Auto;
                using (StreamWriter output = File.CreateText(path)) {
                    using (XmlWriter writer = XmlWriter.Create(output, settings)) {
                        XPathExpression select_xpath = select_expression.Clone();
                        select_xpath.SetContext(context);
                        XPathNodeIterator ni = document.CreateNavigator().Select(select_expression);
                        while (ni.MoveNext())
                        {
                            if (ni.Current.NodeType == XPathNodeType.ProcessingInstruction && ni.Current.Name.Equals("literal-text"))
                            {
                                writer.Flush();
                                output.Write(ni.Current.Value);
                            }
                            else
                            {
                                ni.Current.WriteSubtree(writer);
                            }
                        }
                    }
                }
            }
        }
Exemple #5
0
        public TransformComponent(BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration)
        {
            // load the transforms
            XPathNodeIterator transform_nodes = configuration.Select("transform");

            foreach (XPathNavigator transform_node in transform_nodes)
            {
                // load the transform
                string file = transform_node.GetAttribute("file", String.Empty);
                if (String.IsNullOrEmpty(file))
                {
                    WriteMessage(MessageLevel.Error, "Each transform element must specify a file attribute.");
                }
                file = Environment.ExpandEnvironmentVariables(file);

                Transform transform = null;
                try {
                    transform = new Transform(file);
                } catch (IOException e) {
                    WriteMessage(MessageLevel.Error, String.Format("The transform file '{0}' could not be loaded. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
                } catch (XmlException e) {
                    WriteMessage(MessageLevel.Error, String.Format("The transform file '{0}' is not a valid XML file. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
                } catch (XsltException e) {
                    WriteMessage(MessageLevel.Error, String.Format("The XSL transform '{0}' contains an error. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
                }


                transforms.Add(transform);


                // load any arguments
                XPathNodeIterator argument_nodes = transform_node.Select("argument");
                foreach (XPathNavigator argument_node in argument_nodes)
                {
                    string key = argument_node.GetAttribute("key", String.Empty);
                    if ((key == null) || (key.Length == 0))
                    {
                        WriteMessage(MessageLevel.Error, "When creating a transform argument, you must specify a key using the key attribute");
                    }

                    // set "expand-value" attribute to true to expand environment variables embedded in "value".
                    string expand_attr  = argument_node.GetAttribute("expand-value", String.Empty);
                    bool   expand_value = String.IsNullOrEmpty(expand_attr) ? false : Convert.ToBoolean(expand_attr);

                    string value = argument_node.GetAttribute("value", String.Empty);
                    if ((value != null) && (value.Length > 0))
                    {
                        transform.Arguments.AddParam(key, String.Empty, expand_value ? Environment.ExpandEnvironmentVariables(value) : value);
                    }
                    else
                    {
                        transform.Arguments.AddParam(key, String.Empty, argument_node.Clone());
                    }
                }
            }
        }
Exemple #6
0
        // component logic

        public override void Apply(XmlDocument document, string key)
        {
            // XmlNodeList link_nodes = document.SelectNodes("//referenceLink");
            XPathNodeIterator linkIterator = document.CreateNavigator().Select(referenceLinkExpression);

            XPathNavigator[] linkNodes = BuildComponentUtilities.ConvertNodeIteratorToArray(linkIterator);

            foreach (XPathNavigator linkNode in linkNodes)
            {
                // extract link information
                ReferenceLinkInfo2 link = ReferenceLinkInfo2.Create(linkNode);

                if (link == null)
                {
                    WriteMessage(MessageLevel.Warn, "Invalid referenceLink element.");
                }
                else
                {
                    // determine target, link type, and display options
                    string         targetId = link.Target;
                    DisplayOptions options  = link.DisplayOptions;
                    LinkType2      type     = LinkType2.None;

                    Target target = GetTarget(targetId);
                    if (target == null)
                    {
                        // no such target known; set link type to none and warn
                        type = LinkType2.None;
                        WriteMessage(MessageLevel.Warn, String.Format("Unknown reference link target '{0}'.", targetId));
                    }
                    else
                    {
                        // if overload is prefered and found, change targetId and make link options hide parameters
                        if (link.PreferOverload)
                        {
                            bool isConversionOperator = false;

                            MethodTarget method = target as MethodTarget;
                            if (method != null)
                            {
                                isConversionOperator = method.conversionOperator;
                            }

                            MemberTarget member = target as MemberTarget;

                            // if conversion operator is found, always link to individual topic.
                            if ((member != null) && (!String.IsNullOrEmpty(member.OverloadId)) && !isConversionOperator)
                            {
                                Target overloadTarget = targets[member.OverloadId];
                                if (overloadTarget != null)
                                {
                                    target   = overloadTarget;
                                    targetId = overloadTarget.Id;
                                }
                            }

                            // if individual conversion operator is found, always display parameters.
                            if (isConversionOperator && member != null && (!string.IsNullOrEmpty(member.OverloadId)))
                            {
                                options = options | DisplayOptions.ShowParameters;
                            }
                            else
                            {
                                options = options & ~DisplayOptions.ShowParameters;
                            }
                        }

                        // get stored link type
                        type = target.DefaultLinkType;

                        // if link type is local or index, determine which
                        if (type == LinkType2.LocalOrIndex)
                        {
                            if ((key != null) && targets.Contains(key) && (target.Container == targets[key].Container))
                            {
                                type = LinkType2.Local;
                            }
                            else
                            {
                                type = LinkType2.Index;
                            }
                        }
                    }

                    // links to this page are not live
                    if (targetId == key)
                    {
                        type = LinkType2.Self;
                    }
                    else if ((target != null) && (key != null) && targets.Contains(key) && (target.File == targets[key].File))
                    {
                        type = LinkType2.Self;
                    }

                    // get msdn or external endpoint, if needed
                    string externalUrl = null;
                    if (type == LinkType2.Msdn || type == LinkType2.External)
                    {
                        externalUrl = ResolveExternalUrl(targetId, type);
                        if (String.IsNullOrEmpty(externalUrl))
                        {
                            type = LinkType2.None;
                        }
                    }

                    // write opening link tag and target info
                    XmlWriter writer = linkNode.InsertAfter();
                    switch (type)
                    {
                    case LinkType2.None:
                        writer.WriteStartElement("span");
                        writer.WriteAttributeString("class", "nolink");
                        break;

                    case LinkType2.Self:
                        writer.WriteStartElement("span");
                        writer.WriteAttributeString("class", "selflink");
                        break;

                    case LinkType2.Local:
                        // format link with prefix and/or postfix
                        string href = String.Format(hrefFormat, target.File);

                        // make link relative, if we have a baseUrl
                        if (baseUrl != null)
                        {
                            href = BuildComponentUtilities.GetRelativePath(href, BuildComponentUtilities.EvalXPathExpr(document, baseUrl, "key", key));
                        }

                        writer.WriteStartElement("a");
                        writer.WriteAttributeString("href", href);
                        break;

                    case LinkType2.Index:
                        writer.WriteStartElement("mshelp", "link", "http://msdn.microsoft.com/mshelp");
                        writer.WriteAttributeString("keywords", targetId);
                        writer.WriteAttributeString("tabindex", "0");
                        break;

                    case LinkType2.Msdn:
                    case LinkType2.External:
                        writer.WriteStartElement("a");
                        writer.WriteAttributeString("href", externalUrl);
                        writer.WriteAttributeString("target", linkTarget);
                        break;
                    }

                    // write the link text
                    if (String.IsNullOrEmpty(link.DisplayTarget))
                    {
                        if (link.Contents == null)
                        {
                            if (target != null)
                            {
                                resolver.WriteTarget(target, options, writer);
                            }
                            else
                            {
                                //Console.WriteLine("Attemting to create reference");
                                Reference reference = TextReferenceUtilities.CreateReference(targetId);
                                //Console.WriteLine("Returned");
                                if (reference is InvalidReference)
                                {
                                    WriteMessage(MessageLevel.Warn, String.Format("Invalid reference link target '{0}'.", targetId));
                                }
                                resolver.WriteReference(reference, options, writer);
                            }
                        }
                        else
                        {
                            // write contents to writer
                            link.Contents.WriteSubtree(writer);
                        }
                    }
                    else
                    {
                        //Console.WriteLine("Display target = {0}", link.DisplayTarget);
                        if ((String.Compare(link.DisplayTarget, "content", true) == 0) && (link.Contents != null))
                        {
                            // Use the contents as an XML representation of the display target

                            //Console.WriteLine(link.Contents.NodeType);
                            Reference reference = XmlTargetCollectionUtilities.CreateReference(link.Contents);
                            //Console.WriteLine(reference.GetType().FullName);
                            resolver.WriteReference(reference, options, writer);
                        }
                        if ((String.Compare(link.DisplayTarget, "format", true) == 0) && (link.Contents != null))
                        {
                            // Use the contents as a format string for the display target

                            string format = link.Contents.OuterXml;
                            //Console.WriteLine("format = {0}", format);

                            string       input     = null;
                            StringWriter textStore = new StringWriter();
                            try {
                                XmlWriterSettings settings = new XmlWriterSettings();
                                settings.ConformanceLevel = ConformanceLevel.Fragment;

                                XmlWriter xmlStore = XmlWriter.Create(textStore, settings);
                                try {
                                    if (target != null)
                                    {
                                        resolver.WriteTarget(target, options, xmlStore);
                                    }
                                    else
                                    {
                                        Reference reference = TextReferenceUtilities.CreateReference(targetId);
                                        resolver.WriteReference(reference, options, xmlStore);
                                    }
                                } finally {
                                    xmlStore.Close();
                                }
                                input = textStore.ToString();
                            } finally {
                                textStore.Close();
                            }
                            //Console.WriteLine("input = {0}", input);

                            string output = String.Format(format, input);
                            //Console.WriteLine("output = {0}", output);

                            XmlDocumentFragment fragment = document.CreateDocumentFragment();
                            fragment.InnerXml = output;
                            fragment.WriteTo(writer);

                            //writer.WriteRaw(output);
                        }
                        else if ((String.Compare(link.DisplayTarget, "extension", true) == 0) && (link.Contents != null))
                        {
                            Reference extMethodReference = XmlTargetCollectionUtilities.CreateExtensionMethodReference(link.Contents);
                            resolver.WriteReference(extMethodReference, options, writer);
                        }
                        else
                        {
                            // Use the display target value as a CER for the display target

                            TextReferenceUtilities.SetGenericContext(key);
                            Reference reference = TextReferenceUtilities.CreateReference(link.DisplayTarget);
                            //Console.WriteLine("Reference is {0}", reference.GetType().FullName);
                            resolver.WriteReference(reference, options, writer);
                        }
                    }

                    // write the closing link tag
                    writer.WriteEndElement();
                    writer.Close();
                }

                // delete the original tag
                linkNode.DeleteSelf();
            }
        }
Exemple #7
0
        private void ResolveConceptualLinks(XmlDocument document, string key)
        {
            // find links
            XPathNodeIterator linkIterator = document.CreateNavigator().Select(conceptualLinks);

            // copy them to an array, because enumerating through an XPathNodeIterator
            // fails when the nodes in it are altered
            XPathNavigator[] linkNodes = BuildComponentUtilities.ConvertNodeIteratorToArray(linkIterator);

            foreach (XPathNavigator linkNode in linkNodes)
            {
                ConceptualLinkInfo link = ConceptualLinkInfo.Create(linkNode);

                // determine url, text, and link type
                string   url         = null;
                string   text        = null;
                LinkType type        = LinkType.None;
                bool     isValidLink = validGuid.IsMatch(link.Target);
                if (isValidLink)
                {
                    // a valid link; try to fetch target info
                    TargetInfo target = GetTargetInfoFromCache(link.Target.ToLower());
                    if (target == null)
                    {
                        // no target found; issue warning, set link style to none, and text to in-source fall-back
                        //type = LinkType.None;
                        type = LinkType.Index;
                        text = BrokenLinkDisplayText(link.Target, link.Text);
                        WriteMessage(MessageLevel.Warn, String.Format("Unknown conceptual link target '{0}'.", link.Target));
                    }
                    else
                    {
                        // found target; get url, text, and type from stored info
                        url  = target.Url;
                        text = target.Text;
                        type = target.Type;
                    }
                }
                else
                {
                    // not a valid link; issue warning, set link style to none, and text to invalid target
                    //type = LinkType.None;
                    type = LinkType.Index;
                    text = BrokenLinkDisplayText(link.Target, link.Text);
                    WriteMessage(MessageLevel.Warn, String.Format("Invalid conceptual link target '{0}'.", link.Target));
                }

                // write opening link tag and target info
                XmlWriter writer = linkNode.InsertAfter();
                switch (type)
                {
                case LinkType.None:
                    writer.WriteStartElement("span");
                    writer.WriteAttributeString("class", "nolink");
                    break;

                case LinkType.Local:
                    writer.WriteStartElement("a");
                    writer.WriteAttributeString("href", url);
                    WriteHtmlAttributes(writer, link);
                    break;

                case LinkType.Index:
                    writer.WriteStartElement("mshelp", "link", "http://msdn.microsoft.com/mshelp");
                    writer.WriteAttributeString("keywords", link.Target.ToLower());
                    writer.WriteAttributeString("tabindex", "0");
                    break;

                case LinkType.Id:
                    string xhelp = String.Format("ms-xhelp://?Id={0}", link.Target);
                    writer.WriteStartElement("a");
                    writer.WriteAttributeString("href", xhelp);
                    break;
                }

                // write the link text
                writer.WriteString(text);

                // write the closing link tag
                writer.WriteEndElement();
                writer.Close();

                // delete the original tag
                linkNode.DeleteSelf();
            }
        }
Exemple #8
0
 private void AddTargets(string file, LinkType2 type)
 {
     try {
         XPathDocument document = new XPathDocument(file);
         XmlTargetCollectionUtilities.AddTargets(targets, document.CreateNavigator(), type);
     } catch (XmlSchemaException e) {
         WriteMessage(MessageLevel.Error, String.Format("The reference targets file '{0}' is not valid. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
     } catch (XmlException e) {
         WriteMessage(MessageLevel.Error, String.Format("The reference targets file '{0}' is not well-formed XML. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
     } catch (IOException e) {
         WriteMessage(MessageLevel.Error, String.Format("An access error occured while opening the reference targets file '{0}'. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
     }
 }
        private void ResolveContent(XmlDocument document, XPathNavigator start)
        {
            // for each kind of shared content element
            foreach (SharedContentElement element in elements)
            {
                // find all such elements
                XPathNodeIterator nodeIterator = start.Select(element.Path);
                // Console.WriteLine("Found {0} shared content elements.", nodeIterator.Count);

                // convert to an array so as not to cause an error when manipulating the document
                XPathNavigator[] nodes = ConvertIteratorToArray(nodeIterator);

                // process each element
                foreach (XPathNavigator node in nodes)
                {
                    // Console.WriteLine(node.LocalName);

                    // get the key
                    string item = node.Evaluate(element.Item).ToString().ToLower();

                    // check for missing key
                    if (String.IsNullOrEmpty(item))
                    {
                        WriteMessage(MessageLevel.Warn, "A shared content element did not specify an item.");
                    }
                    else
                    {
                        // Console.WriteLine("node={0}", node.OuterXml);

                        // extract parameters
                        List <string>     parameters      = new List <string>();
                        XPathNodeIterator parameter_nodes = node.Select(element.Parameters);
                        foreach (XPathNavigator parameter_node in parameter_nodes)
                        {
                            string parameter = BuildComponentUtilities.GetInnerXml(parameter_node);
                            // Console.WriteLine("parameter={0}", parameter);
                            parameters.Add(parameter);
                        }

                        // get the content
                        string content = GetContent(item, parameters.ToArray());

                        // check for missing content
                        if (content == null)
                        {
                            WriteMessage(MessageLevel.Warn, String.Format("Missing shared content item. Tag:'{0}'; Id:'{1}'.", node.LocalName, item));
                        }
                        else
                        {
                            // store the content in a document fragment
                            XmlDocumentFragment fragment = document.CreateDocumentFragment();
                            fragment.InnerXml = content;

                            // resolve any shared content in the fragment
                            ResolveContent(document, fragment.CreateNavigator());
                            //string resolvedContent = fragment.InnerXml;
                            //Console.WriteLine("value = '{0}'", resolvedContent);

                            // look for an attribute name
                            string attribute = node.Evaluate(element.Attribute).ToString();

                            // insert the resolved content
                            if (String.IsNullOrEmpty(attribute))
                            {
                                // as mixed content
                                // node.InsertAfter(resolvedContent);
                                XmlWriter writer = node.InsertAfter();
                                fragment.WriteTo(writer);
                                writer.Close();
                            }
                            else
                            {
                                // as an attribute
                                XPathNavigator parent = node.CreateNavigator();
                                parent.MoveToParent();
                                parent.CreateAttribute(String.Empty, attribute, String.Empty, fragment.InnerText);
                            }
                        }
                    }

                    // keep a reference to the parent element
                    XPathNavigator parentElement = node.CreateNavigator();
                    parentElement.MoveToParent();

                    // remove the node
                    node.DeleteSelf();

                    // if there is no content left in the parent element, make sure it is self-closing
                    if (!parentElement.HasChildren && !parentElement.IsEmptyElement)
                    {
                        //If 'node' was already the root then we will have a blank node now and
                        //doing an InsertAfter() will throw an exception.
                        if (parentElement.Name.Length > 0)
                        {
                            // create a new element
                            XmlWriter attributeWriter = parentElement.InsertAfter();
                            attributeWriter.WriteStartElement(parentElement.Prefix, parentElement.LocalName, parentElement.NamespaceURI);

                            // copy attributes to it
                            XmlReader attributeReader = parentElement.ReadSubtree();
                            attributeReader.Read();
                            attributeWriter.WriteAttributes(attributeReader, false);
                            attributeReader.Close();

                            // close it
                            attributeWriter.WriteEndElement();
                            attributeWriter.Close();

                            // delete the old element
                            parentElement.DeleteSelf();
                        }
                        else
                        {
                            //if we are inside a tag such as title, removing the content will make it in the
                            //form of <title /> which is not allowed in html.
                            //Since this usually means there is a problem with the shared content or the transforms
                            //leading up to this we will just report the error here.
                            WriteMessage(MessageLevel.Error, "Error replacing item.");
                        }
                    }
                }
            }
        }
        private void LoadContent(string file)
        {
            WriteMessage(MessageLevel.Info, String.Format("Loading shared content file '{0}'.", file));

            try {
                XmlReader reader = XmlReader.Create(file);

                try {
                    reader.MoveToContent();
                    while (!reader.EOF)
                    {
                        if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "item"))
                        {
                            string key   = reader.GetAttribute("id").ToLower();
                            string value = reader.ReadInnerXml();

                            if (content.ContainsKey(key))
                            {
                                WriteMessage(MessageLevel.Info, String.Format("Overriding shared content item '{0}' with value in file '{1}'.", key, file));
                            }
                            content[key] = value;
                            // content.Add(key, value);
                        }
                        else
                        {
                            reader.Read();
                        }
                    }
                } finally {
                    reader.Close();
                }
            } catch (IOException e) {
                WriteMessage(MessageLevel.Error, String.Format("The shared content file '{0}' could not be opened. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
            } catch (XmlException e) {
                WriteMessage(MessageLevel.Error, String.Format("The shared content file '{0}' is not well-formed. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
            } catch (XmlSchemaException e) {
                WriteMessage(MessageLevel.Error, String.Format("The shared content file '{0}' is not valid. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
            }
        }
Exemple #11
0
        // the actual work of the component

        public override void Apply(XmlDocument document, string key)
        {
            XPathNodeIterator nodesIterator = document.CreateNavigator().Select(selector);

            XPathNavigator[] nodes = BuildComponentUtilities.ConvertNodeIteratorToArray(nodesIterator);
            foreach (XPathNavigator node in nodes)
            {
                string reference = node.Value;

                // check for validity of reference
                if (validSnippetReference.IsMatch(reference))
                {
                    SnippetIdentifier[] identifiers = SnippetIdentifier.ParseReference(reference);

                    if (identifiers.Length == 1)
                    {
                        // one snippet referenced

                        SnippetIdentifier    identifier = identifiers[0];
                        List <StoredSnippet> values;
                        if (snippets.TryGetValue(identifier, out values))
                        {
                            XmlWriter writer = node.InsertAfter();
                            writer.WriteStartElement("snippets");
                            writer.WriteAttributeString("reference", reference);

                            foreach (StoredSnippet value in values)
                            {
                                writer.WriteStartElement("snippet");
                                writer.WriteAttributeString("language", value.Language);

                                if (colorization.ContainsKey(value.Language))
                                {
                                    WriteColorizedSnippet(ColorizeSnippet(value.Text, colorization[value.Language]), writer);
                                }
                                else
                                {
                                    writer.WriteString(value.Text);
                                    //writer.WriteString(System.Web.HttpUtility.HtmlDecode(value.Text));
                                }
                                writer.WriteEndElement();
                            }

                            writer.WriteEndElement();
                            writer.Close();
                        }
                        else
                        {
                            WriteMessage(MessageLevel.Warn, String.Format("No snippet with identifier '{0}' was found.", identifier));
                        }
                    }
                    else
                    {
                        // multiple snippets referenced

                        // create structure that maps language -> snippets
                        Dictionary <string, List <StoredSnippet> > map = new Dictionary <string, List <StoredSnippet> >();
                        foreach (SnippetIdentifier identifier in identifiers)
                        {
                            List <StoredSnippet> values;
                            if (snippets.TryGetValue(identifier, out values))
                            {
                                foreach (StoredSnippet value in values)
                                {
                                    List <StoredSnippet> pieces;
                                    if (!map.TryGetValue(value.Language, out pieces))
                                    {
                                        pieces = new List <StoredSnippet>();
                                        map.Add(value.Language, pieces);
                                    }
                                    pieces.Add(value);
                                }
                            }
                        }

                        XmlWriter writer = node.InsertAfter();
                        writer.WriteStartElement("snippets");
                        writer.WriteAttributeString("reference", reference);

                        foreach (KeyValuePair <string, List <StoredSnippet> > entry in map)
                        {
                            writer.WriteStartElement("snippet");
                            writer.WriteAttributeString("language", entry.Key);

                            List <StoredSnippet> values = entry.Value;
                            for (int i = 0; i < values.Count; i++)
                            {
                                if (i > 0)
                                {
                                    writer.WriteString("\n...\n\n\n");
                                }
                                writer.WriteString(values[i].Text);
                                // writer.WriteString(System.Web.HttpUtility.HtmlDecode(values[i].Text));
                            }

                            writer.WriteEndElement();
                        }

                        writer.WriteEndElement();
                        writer.Close();
                    }
                }
                else
                {
                    WriteMessage(MessageLevel.Warn, String.Format("The code reference '{0}' is not well-formed", reference));
                }

                node.DeleteSelf();
            }
        }
        public override void Apply(XmlDocument document, string id)
        {
            XPathNodeIterator artLinkIterator = document.CreateNavigator().Select(artLinkExpression);

            XPathNavigator[] artLinks = BuildComponentUtilities.ConvertNodeIteratorToArray(artLinkIterator);
            foreach (XPathNavigator artLink in artLinks)
            {
                string name = artLink.GetAttribute("target", String.Empty).ToLower();

                if (targets.ContainsKey(name))
                {
                    ArtTarget target = targets[name];

                    // evaluate the path
                    string path = document.CreateNavigator().Evaluate(target.OutputXPath).ToString();

                    if (target.baseOutputPath != null)
                    {
                        path = Path.Combine(target.baseOutputPath, path);
                    }
                    string outputPath = Path.Combine(path, target.Name);

                    string targetDirectory = Path.GetDirectoryName(outputPath);

                    if (!Directory.Exists(targetDirectory))
                    {
                        Directory.CreateDirectory(targetDirectory);
                    }

                    if (File.Exists(target.InputPath))
                    {
                        if (File.Exists(outputPath))
                        {
                            File.SetAttributes(outputPath, FileAttributes.Normal);
                        }

                        File.Copy(target.InputPath, outputPath, true);
                    }
                    else
                    {
                        WriteMessage(MessageLevel.Warn, String.Format("The file '{0}' for the art target '{1}' was not found.", target.InputPath, name));
                    }

                    // Get the relative art path for HXF generation.
                    int    index   = target.LinkPath.IndexOf('/');
                    string artPath = target.LinkPath.Substring(index + 1, target.LinkPath.Length - (index + 1));

                    FileCreatedEventArgs fe = new FileCreatedEventArgs(artPath, Path.GetDirectoryName(path));
                    OnComponentEvent(fe);

                    XmlWriter writer = artLink.InsertAfter();

                    writer.WriteStartElement("img");
                    if (!String.IsNullOrEmpty(target.Text))
                    {
                        writer.WriteAttributeString("alt", target.Text);
                    }

                    if (target.FormatXPath == null)
                    {
                        writer.WriteAttributeString("src", target.LinkPath);
                    }
                    else
                    {
                        // WebDocs way, which uses the 'format' xpath expression to calculate the target path
                        // and then makes it relative to the current page if the 'relative-to' attribute is
                        // used.
                        string src = BuildComponentUtilities.EvalXPathExpr(document, target.FormatXPath, "key", Path.GetFileName(outputPath));
                        if (target.RelativeToXPath != null)
                        {
                            src = BuildComponentUtilities.GetRelativePath(src, BuildComponentUtilities.EvalXPathExpr(document, target.RelativeToXPath, "key", id));
                        }
                        writer.WriteAttributeString("src", src);
                    }

                    writer.WriteEndElement();

                    writer.Close();

                    artLink.DeleteSelf();
                }
                else
                {
                    WriteMessage(MessageLevel.Warn, String.Format("Unknown art target '{0}'", name));
                }
            }
        }