Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Nant';s xmlpoke目标以删除节点_Xml_Nant_Xmlpoke - Fatal编程技术网

如何使用Nant';s xmlpoke目标以删除节点

如何使用Nant';s xmlpoke目标以删除节点,xml,nant,xmlpoke,Xml,Nant,Xmlpoke,给定以下xml: <rootnode> <childnode arg="a">Content A</childnode> <childnode arg="b">Content A</childnode> </rootnode> 结果(如果替换字符串为空)为: 内容A 当我们实际希望删除childnode本身时,childnode的内容已被删除。预期的结果是: <rootnode> <

给定以下xml:

<rootnode>
   <childnode arg="a">Content A</childnode>
   <childnode arg="b">Content A</childnode>
</rootnode>
结果(如果替换字符串为空)为:


内容A
当我们实际希望删除childnode本身时,childnode的内容已被删除。预期的结果是:

<rootnode>
   <childnode arg="a">Content A</childnode>
</rootnode>

内容A

必须根据childnode参数选择childnode。

我举手!这是问错问题的典型案例

问题是不能使用xmlpoke删除单个节点。Xmlpoke只能用于编辑特定节点或属性的内容。根据问题,仅使用标准Nant目标并没有一种优雅的方法来删除子节点。可以使用Nant中的属性使用一些不雅观的字符串操作来完成,但是为什么要这样做呢

最好的方法是编写一个简单的Nant目标。这是我之前准备的一个:

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

namespace XmlStrip
{
    [TaskName("xmlstrip")]
    public class XmlStrip : Task
    {
        [TaskAttribute("xpath", Required = true), StringValidator(AllowEmpty = false)]
        public string XPath { get; set; }

        [TaskAttribute("file", Required = true)]
        public FileInfo XmlFile { get; set; }

        protected override void ExecuteTask()
        {
            string filename = XmlFile.FullName;
            Log(Level.Info, "Attempting to load XML document in file '{0}'.", filename );
            XmlDocument document = new XmlDocument();
            document.Load(filename);
            Log(Level.Info, "XML document in file '{0}' loaded successfully.", filename );

            XmlNode node = document.SelectSingleNode(XPath);
            if(null == node)
            {
                throw new BuildException(String.Format("Node not found by XPath '{0}'", XPath));
            }

            node.ParentNode.RemoveChild(node);

            Log(Level.Info, "Attempting to save XML document to '{0}'.", filename );
            document.Save(filename);
            Log(Level.Info, "XML document successfully saved to '{0}'.", filename );
        }
    }
}
将上述内容与对NAnt.exe.config文件的修改结合起来,以在生成文件中加载自定义目标和以下脚本:



这将从target.xml中删除带有参数arg且值为b的childnode。这正是我一开始想要的

xmlpeek
仅读取值。
xmlpoke
仅设置值。 不幸的是,nant没有xmldelete任务

我通过在nant文件中创建一个nant
解决了这个问题,我可以很容易地在项目之间重复使用

我选择利用nant内置的
任务

优势:
  • 与正则表达式一起使用(请参见缺点)
  • 可以匹配任何文本,包括XML
缺点:
  • 你曾经用正则表达式解决过问题吗?如果是,您现在有另一个问题
  • nant文件中的正则表达式值必须转义!(使用在线xml转义器工具)

下面是如何包括和调用此目标。请记住,所有参数都是全局的,必须在调用目标之前定义

  • delete.from.file.path
    :要修改的文件的路径
  • delete.from.file.regex
    :与要删除的内容匹配的正则表达式(并定义组之前和之后)


为我节省了一些时间。谢谢你!这对名称空间有用吗?这个答案很好地补充了@Iain的答案。它的优点之一是不需要任何额外的编译和配置。
<rootnode>
   <childnode arg="a">Content A</childnode>
</rootnode>
using System;
using System.IO;
using System.Xml;
using NAnt.Core;
using NAnt.Core.Attributes;

namespace XmlStrip
{
    [TaskName("xmlstrip")]
    public class XmlStrip : Task
    {
        [TaskAttribute("xpath", Required = true), StringValidator(AllowEmpty = false)]
        public string XPath { get; set; }

        [TaskAttribute("file", Required = true)]
        public FileInfo XmlFile { get; set; }

        protected override void ExecuteTask()
        {
            string filename = XmlFile.FullName;
            Log(Level.Info, "Attempting to load XML document in file '{0}'.", filename );
            XmlDocument document = new XmlDocument();
            document.Load(filename);
            Log(Level.Info, "XML document in file '{0}' loaded successfully.", filename );

            XmlNode node = document.SelectSingleNode(XPath);
            if(null == node)
            {
                throw new BuildException(String.Format("Node not found by XPath '{0}'", XPath));
            }

            node.ParentNode.RemoveChild(node);

            Log(Level.Info, "Attempting to save XML document to '{0}'.", filename );
            document.Save(filename);
            Log(Level.Info, "XML document successfully saved to '{0}'.", filename );
        }
    }
}
<xmlstrip xpath="//rootnode/childnode[@arg = 'b']" file="target.xml" />