2009-02-11 3 views
13

Angesichts der folgenden xml entfernen:Wie kann ich Nant des xmlpoke Ziel einen Knoten

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

Mit XMLPoke mit folgendem XPath:

rootnode/childnode[arg='b'] 

Das Ergebnis (wenn die Zeichenfolge leer ersetzen) ist:

Der Inhalt des Childnode wurde entfernt, wenn wir eigentlich das Kindno wollen de selbst entfernt. Das gewünschte Ergebnis lautet:

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

Der Childnode muss basierend auf dem Childnode-Argument ausgewählt werden.

Antwort

24

Ich halte meine Hände hoch! Dies ist ein klassischer Fall, bei dem die falsche Frage gestellt wird. Das Problem besteht darin, dass Sie xmlpoke nicht verwenden können, um einen einzelnen Knoten zu entfernen. Xmlpoke kann nur zum Bearbeiten des Inhalts eines bestimmten Knotens oder Attributs verwendet werden. Es gibt keine elegante Möglichkeit, einen untergeordneten Knoten gemäß der Frage zu entfernen, indem nur die Standardziele Nant verwendet werden. Es kann mit einigen uneleganten String-Manipulation mit Eigenschaften in Nant getan werden, aber warum möchten Sie?

Der beste Weg, dies zu tun, ist ein einfaches Nant-Ziel zu schreiben. Hier ist ein ich bereits vorbereitet:

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

die obige Kombinieren mit einer Modifikation der NAnt.exe.config Datei des benutzerdefinierten Ziel zu laden und das folgende Skript in der build Datei:

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

Dies wird die childNode mit einem Argument Arg- mit Wert b von target.xm entfernen l. Was ich eigentlich eigentlich wollte!

+1

rettete mich etwas Zeit. Danke dafür! – aleemb

+1

Vielen Dank für die Veröffentlichung der Quelle. –