Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Christian Palm 277 posts 272 karma points
    Jul 02, 2010 @ 11:50
    Christian Palm
    1

    NAnt task: AppendXml - nant task when creating umbraco packages via build script

    Just a little cool nant task I would like to share.
    It is mainly targeted developers wich are building packages via build script.

    The nant task xmlpeek and xmlpoke are quite simple and it is difficult to append xml nodes to xml files. You can do it though but the build script will be harder to maintain.

    The task can take a node list from a source xml document and append it to a node in a target xml document

    <appendxml
    sourcefile="${dir}/Publication.Module.Dictionary.xml"
    sourcexpath="/umbPackage/DictionaryItems/DictionaryItem"
    targetfile="${dir}/package.xml"
    targetxpath="/umbPackage/DictionaryItems"  />

    The source code for the task is in the bottom

    Example files:

    AppendDictionaries.build

    <?xml version="1.0"?>
    <project name="Foundation"
    default="">
      <property name="dir"
    value="${directory::get-current-directory()}" />
      <target
    name="AppendDictionaries" description="Add the publication and news
    module dictionaries into the main package file">
        <appendxml
    sourcefile="${dir}/Publication.Module.Dictionary.xml"
    sourcexpath="/umbPackage/DictionaryItems/DictionaryItem"
    targetfile="${dir}/package.xml"
    targetxpath="/umbPackage/DictionaryItems"  />
        <appendxml
    sourcefile="${dir}/News.Module.Dictionary.xml"
    sourcexpath="/umbPackage/DictionaryItems/DictionaryItem"
    targetfile="${dir}/package.xml"
    targetxpath="/umbPackage/DictionaryItems"  />
      </target>
    </project>


    package.xml

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <umbPackage>
    <files />
    <info>
    <package>
    <name>The cool foundation</name>
    <version></version>
    <license url="http://www.opensource.org/licenses/mit-license.php">MIT license</license>
    <url>http://www.cpalm.dk</url>;
    <requirements>
    <major>4</major>
    <minor>0</minor>
    <patch>3</patch>
    </requirements>
    </package>
    <author>
    <name>Christian Palm</name>
    <website>http://www.cpalm.dk</website>;
    </author>
    <readme><![CDATA[]]></readme>
    </info>
    <Documents></Documents>
    <DocumentTypes> </DocumentTypes>
    <Templates></Templates>
    <Stylesheets></Stylesheets>
    <Macros />
    <DictionaryItems />
    <Languages />
    <Actions></Actions>
    <DataTypes></DataTypes>
    <control></control>
    </umbPackage>


    Publication.Module.Dictionary.xml

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <umbPackage>
    <DictionaryItems>
        <DictionaryItem Key="PublicationModule">
          <Value LanguageId="1" LanguageCultureAlias="en-US">
    <![CDATA[Testing]]>
    </Value>
    <DictionaryItem Key="PublicationModule-Title">
    <Value LanguageId="1" LanguageCultureAlias="en-US">
    <![CDATA[Publication module]]>
    </Value>
          </DictionaryItem>
    </DictionaryItem>
      </DictionaryItems>
    </umbPackage>


    News.Module.Dictionary.xml

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <umbPackage>
    <DictionaryItems>
        <DictionaryItem Key="NewsModule">
    <Value LanguageId="1" LanguageCultureAlias="en-US">
    <![CDATA[Testing]]>
    </Value>
    <DictionaryItem Key="NewsModule-Title">
            <Value LanguageId="1" LanguageCultureAlias="en-US">
    <![CDATA[News module]]>
    </Value>
         </DictionaryItem>
    </DictionaryItem>
      </DictionaryItems>
    </umbPackage>


    Updated package.xml

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <umbPackage>
    <files />
        <info>
    ...
            <!-- skipped in example -->
    ...
        </info>
    <Documents></Documents>
        <DocumentTypes></DocumentTypes>
        <Templates></Templates>
    <Stylesheets></Stylesheets>
        <Macros />
    <DictionaryItems>
          <DictionaryItem Key="PublicationModule">
            <Value LanguageId="1" LanguageCultureAlias="en-US">
       <![CDATA[Testing]]>
       </Value>
      <DictionaryItem Key="PublicationModule-Title">
       <Value LanguageId="1" LanguageCultureAlias="en-US">
       <![CDATA[Publication module]]>
       </Value>
            </DictionaryItem>
       </DictionaryItem>
          <DictionaryItem Key="NewsModule">
       <Value LanguageId="1" LanguageCultureAlias="en-US">
       <![CDATA[Testing]]>
       </Value>
       <DictionaryItem Key="NewsModule-Title">
              <Value LanguageId="1" LanguageCultureAlias="en-US">
       <![CDATA[News module]]>
       </Value>
           </DictionaryItem>
       </DictionaryItem>
        </DictionaryItems>
    <Languages />
        <Actions></Actions>
    <DataTypes></DataTypes>
    <control></control>
    </umbPackage>


    AppendXmlTask.cs

    using System.IO;
    using System.Xml;
    using NAnt.Core;
    using
    NAnt.Core.Attributes;

    namespace CPalm.NantTasks
    {
        ///
    <summary>
        /// Appends nodes from a source xml document to a
    target xml document
        /// </summary>
       
    [TaskName("appendxml")]
        public class AppendXmlTask : Task
        {
           
    [TaskAttribute("sourcefile", Required = true)]
           
    [StringValidator(AllowEmpty = false)]
            public string
    SourceFile { get; set; }

            [TaskAttribute("sourcexpath",
    Required = true)]
            [StringValidator(AllowEmpty = false)]
           
    public string SourceXPath { get; set; }

           
    [TaskAttribute("targetfile", Required = true)]
           
    [StringValidator(AllowEmpty = false)]
            public string
    Targetfile { get; set; }

            [TaskAttribute("targetxpath",
    Required = true)]
            [StringValidator(AllowEmpty = false)]
           
    public string TargetXPath { get; set; }

            protected
    override void ExecuteTask()
            {
                //Check the file
    exists
                string sourceDocPath =
    Project.ExpandProperties(SourceFile, Location);
                if
    (File.Exists(sourceDocPath) == false)
                {
                   
    throw new BuildException("The sourcefile specified does not exist");
               
    }

                string targetDocPath =
    Project.ExpandProperties(Targetfile, Location);
                if
    (File.Exists(targetDocPath) == false)
                {
                   
    throw new BuildException("The targetfile specified does not exist");
               
    }

                XmlDocument sourceDoc = new XmlDocument();
               
    FileStream fsSourceRead = new FileStream(sourceDocPath, FileMode.Open,
    FileAccess.Read, FileShare.Read);
               
    sourceDoc.Load(fsSourceRead);
                fsSourceRead.Dispose();

               
    XmlNodeList sourceNodes = sourceDoc.SelectNodes(SourceXPath);
               
    if (sourceNodes.Count < 1)
                {
                   
    Project.Log(Level.Warning, "No nodes found via XPath in source file!");
               
    }
                else
                {
                   
    Project.Log(Level.Info, string.Format("Found {0} nodes in source file
    via XPath", sourceNodes.Count));

                    XmlDocument
    targetDoc = new XmlDocument();
                    FileStream
    fsTargetRead = new FileStream(targetDocPath, FileMode.Open,
    FileAccess.Read, FileShare.Read);
                   
    targetDoc.Load(fsTargetRead);
                    fsTargetRead.Dispose();

                   
    XmlNodeList targetNodes = targetDoc.SelectNodes(TargetXPath);
                   
    if (targetNodes.Count < 0)
                    {
                       
    Project.Log(Level.Warning, "No target node found via XPath in target
    file!");
                    }
                    else if
    (targetNodes.Count > 1)
                    {
                       
    Project.Log(Level.Warning, string.Format("{0} nodes found when trying to
    find one target node found via XPath in target file!",
    targetNodes.Count));
                    }
                    else
                   
    {
                        XmlNode targetNode = targetNodes[0];
                       
    foreach (XmlNode sourceNode in sourceNodes)
                        {
                           
    XmlNode newNode = targetDoc.ImportNode(sourceNode, true);
                           
    targetNode.AppendChild(newNode);
                        }

                       
    FileStream fsWrite = new FileStream(targetDocPath, FileMode.Truncate,
    FileAccess.Write, FileShare.ReadWrite);
                        try
                       
    {
                            targetDoc.Save(fsWrite);
                       
    }
                        finally
                        {
                           
    fsWrite.Dispose();
                        }
                       
    Project.Log(Level.Info, "New nodes imported");
                    }
              
    }
            }
        }
    }
Please Sign in or register to post replies

Write your reply to:

Draft