예제 #1
0
        public override XmlElement GetXml()
        {
            XmlDocumentFragment df = doc.CreateDocumentFragment();
            XmlWriter           w  = df.CreateNavigator().AppendChild();

            serializer.WriteKeyIdentifierClause(w, clause);
            w.Close();
            return((XmlElement)df.FirstChild);
        }
예제 #2
0
        /// <summary>
        /// Look up the shared content elements, find their corresponding shared content item and replace the
        /// elements with the content item value.
        /// </summary>
        /// <param name="key">The document key</param>
        /// <param name="document">The document containing the topic</param>
        /// <param name="start">The XPath navigator to search for content elements</param>
        /// <remarks>This method will replace content items within other content items recursively</remarks>
        private void ResolveContent(string key, XmlDocument document, XPathNavigator start)
        {
            List <string> parameters = new List <string>();

            // For each kind of shared content element...
            foreach (SharedContentElement element in elements)
            {
                // Find all such elements, convert to an array so as not to cause an error when manipulating the
                // document, and process each element.
                foreach (XPathNavigator node in start.Select(element.Path).ToArray())
                {
                    // Get the item key
                    string item = node.Evaluate(element.Item).ToString();

                    // Check for a missing item key
                    if (String.IsNullOrEmpty(item))
                    {
                        this.WriteMessage(key, MessageLevel.Warn, "A shared content element did not specify an item");
                    }
                    else
                    {
                        // Extract any parameters
                        parameters.Clear();

                        XPathNodeIterator parameterNodes = node.Select(element.Parameters);

                        foreach (XPathNavigator parameterNode in parameterNodes)
                        {
                            parameters.Add(parameterNode.GetInnerXml());
                        }

                        // Find the content item and format the parameters into the value
                        string contentValue = null;

                        if (content.TryGetValue(item, out contentValue))
                        {
                            try
                            {
                                contentValue = String.Format(CultureInfo.InvariantCulture, contentValue,
                                                             parameters.ToArray());
                            }
                            catch (FormatException)
                            {
                                this.WriteMessage(key, MessageLevel.Error, "The shared content item '{0}' " +
                                                  "could not be formatted with {1} parameters.", item, parameters.Count);
                            }
                        }

                        // Check for missing content
                        if (contentValue == null)
                        {
                            this.WriteMessage(key, MessageLevel.Warn, "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 = contentValue;

                            // Resolve any shared content in the fragment
                            this.ResolveContent(key, document, fragment.CreateNavigator());

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

                            // Insert the resolved content...
                            if (String.IsNullOrEmpty(attribute))
                            {
                                // ...as mixed content
                                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 the 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 leave it in the
                            // form "<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.
                            this.WriteMessage(key, MessageLevel.Error, "Error replacing item.  Root document " +
                                              "element encountered.");
                        }
                    }
                }
            }
        }
예제 #3
0
        private void ResolveContent(XmlDocument document, XPathNavigator start)
        {
            if (_pathSelector == null)
            {
                return;
            }

            // find all such elements
            XPathNodeIterator nodeIterator = start.Select(_pathSelector);

            if (nodeIterator == null || nodeIterator.Count == 0)
            {
                return;
            }

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

            // process each element
            int nodeCount = nodes.Length;

            for (int i = 0; i < nodeCount; i++)
            {
                XPathNavigator node = nodes[i];
                // get the key
                string item = node.Evaluate(_itemSelector).ToString();

                // check for missing key
                if (String.IsNullOrEmpty(item))
                {
                    LogMessage(BuildLoggerLevel.Warn,
                               "A shared content element did not specify an item.");
                }
                else
                {
                    // extract parameters
                    List <string>     parameters      = new List <string>();
                    XPathNodeIterator parameter_nodes = node.Select(_parametersSelector);
                    foreach (XPathNavigator parameter_node in parameter_nodes)
                    {
                        string parameter = GetInnerXml(parameter_node);
                        parameters.Add(parameter);
                    }

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

                    // check for missing content
                    if (content == null)
                    {
                        if (_warnIfNotFound)
                        {
                            LogMessage(BuildLoggerLevel.Warn, String.Format(
                                           "Missing shared content item. Tag:'{0}'; Id:'{1}'.",
                                           node.LocalName, item));
                        }
                        if (_deleteIfNotFound)
                        {
                            node.DeleteSelf();
                        }
                    }
                    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());

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

                        // insert the resolved content
                        if (String.IsNullOrEmpty(attribute))
                        {
                            // as mixed content
                            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.
                        LogMessage(BuildLoggerLevel.Error, "Error replacing item.");
                    }
                }
            }
        }