diff options
Diffstat (limited to 'tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromFileComponent.cs')
-rw-r--r-- | tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromFileComponent.cs | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromFileComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromFileComponent.cs new file mode 100644 index 0000000..54d26e0 --- /dev/null +++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromFileComponent.cs @@ -0,0 +1,143 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Xml; +using System.Xml.XPath; + +namespace Microsoft.Ddue.Tools { + + public class CopyFromFileComponent : BuildComponent { + + public CopyFromFileComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) { + + if (configuration == null) throw new ArgumentNullException("configuration"); + + string data_name = null; + + // get information about the data file + XPathNodeIterator data_nodes = configuration.Select("data"); + foreach (XPathNavigator data_node in data_nodes) { + string data_file = data_node.GetAttribute("file", String.Empty); + if (String.IsNullOrEmpty(data_file)) WriteMessage(MessageLevel.Error, "Data elements must have a file attribute specifying a file from which to load data."); + data_file = Environment.ExpandEnvironmentVariables(data_file); + + data_name = data_node.GetAttribute("name", String.Empty); + if (String.IsNullOrEmpty(data_name)) data_name = Guid.NewGuid().ToString(); + + // load a schema, if one is specified + string schema_file = data_node.GetAttribute("schema", String.Empty); + XmlReaderSettings settings = new XmlReaderSettings(); + if (!String.IsNullOrEmpty(schema_file)) { + settings.Schemas.Add(null, schema_file); + } + + // load the document + WriteMessage(MessageLevel.Info, String.Format("Loading data file '{0}'.", data_file) ); + using (XmlReader reader = XmlReader.Create(data_file, settings)) { + XPathDocument data_document = new XPathDocument(reader); + Data.Add(data_name, data_document); + } + } + + + // get the source and target expressions for each copy command + XPathNodeIterator copy_nodes = configuration.Select("copy"); + foreach (XPathNavigator copy_node in copy_nodes) { + string source_name = copy_node.GetAttribute("name", String.Empty); + if (String.IsNullOrEmpty(source_name)) source_name = data_name; + + XPathDocument source_document = (XPathDocument) Data[source_name]; + + string source_xpath = copy_node.GetAttribute("source", String.Empty); + if (String.IsNullOrEmpty(source_xpath)) throw new ConfigurationErrorsException("When instantiating a CopyFromFile component, you must specify a source xpath format using the source attribute."); + string target_xpath = copy_node.GetAttribute("target", String.Empty); + if (String.IsNullOrEmpty(target_xpath)) throw new ConfigurationErrorsException("When instantiating a CopyFromFile component, you must specify a target xpath format using the target attribute."); + copy_commands.Add( new CopyFromFileCommand(source_document, source_xpath, target_xpath) ); + } + + } + + // private XPathDocument data_document; + + private List<CopyFromFileCommand> copy_commands = new List<CopyFromFileCommand>(); + + private CustomContext context = new CustomContext(); + + // the work of the component + + public override void Apply (XmlDocument document, string key) { + + // set the key in the XPath context + context["key"] = key; + + // iterate over the copy commands + foreach (CopyFromFileCommand copy_command in copy_commands) { + + // extract the target node + XPathExpression target_xpath = copy_command.Target.Clone(); + target_xpath.SetContext(context); + XPathNavigator target = document.CreateNavigator().SelectSingleNode(target_xpath); + + // warn if target not found? + if (target == null) { + continue; + } + + // extract the source nodes + XPathExpression source_xpath = copy_command.Source.Clone(); + source_xpath.SetContext(context); + XPathNodeIterator sources = copy_command.SourceDocument.CreateNavigator().Select(source_xpath); + + // warn if source not found? + + // append the source nodes to the target node + foreach (XPathNavigator source in sources) { + target.AppendChild(source); + } + + } + + } + + } + + + // a representation of a copying operation + + internal class CopyFromFileCommand { + + public CopyFromFileCommand (XPathDocument source_document, string source_xpath, string target_xpath) { + this.source_document = source_document; + source = XPathExpression.Compile(source_xpath); + target = XPathExpression.Compile(target_xpath); + } + + private XPathDocument source_document; + + private XPathExpression source; + + private XPathExpression target; + + public XPathDocument SourceDocument { + get { + return(source_document); + } + } + + public XPathExpression Source { + get { + return(source); + } + } + + public XPathExpression Target { + get { + return(target); + } + } + + } + +} |