2009-02-11 33 views
13

Với xml sau:Làm thế nào tôi có thể sử dụng mục tiêu xmlpoke Nant để loại bỏ một nút

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

Sử dụng XMLPoke với XPath sau:

rootnode/childnode[arg='b'] 

Kết quả (nếu thay thế chuỗi rỗng) là:

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

Nội dung của mã con bị xóa khi chúng tôi thực sự muốn childno tự xóa. Kết quả mong muốn là:

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

Mã con phải được chọn dựa trên đối số khóa con.

Trả lời

24

Tôi giơ tay lên! Đây là một trường hợp cổ điển khi đặt câu hỏi sai.

Sự cố là bạn không thể sử dụng xmlpoke để xóa một nút. Xmlpoke chỉ có thể được sử dụng để chỉnh sửa nội dung của một nút hoặc thuộc tính cụ thể. Không có cách nào thanh lịch để xóa nút con theo câu hỏi chỉ sử dụng các mục tiêu tiêu chuẩn Nant tiêu chuẩn. Nó có thể được thực hiện bằng cách sử dụng một số thao tác chuỗi không phù hợp bằng cách sử dụng các thuộc tính ở Nant, nhưng tại sao bạn muốn?

Cách tốt nhất để làm điều này là viết một mục tiêu Nant đơn giản. Dưới đây là một tôi đã chuẩn bị trước đó:

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); 
     } 
    } 
} 

Kết hợp trên với một sửa đổi để các tập tinNAnt.exe.config để nạp mục tiêu tùy chỉnh và kịch bản sau đây trong build file:

<xmlstrip xpath="//rootnode/childnode[@arg = 'b']" file="target.xml" /> 

Thao tác này sẽ xóa mã con bằng đối số arg với giá trị b từ target.xm l. Đó là những gì tôi thực sự muốn ở nơi đầu tiên!

+1

Đã lưu tôi một thời gian. Cám ơn vì cái này! – aleemb

+1

Cảm ơn bạn đã đăng nguồn. –

Các vấn đề liên quan