xml
  • nant
  • xmlpoke
  • 2009-02-11 17 views 13 likes 
    13

    Dato il seguente XML:Come si usa bersaglio xmlpoke di Nant per rimuovere un nodo

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

    Uso XMLPoke con la seguente XPath:

    rootnode/childnode[arg='b'] 
    

    Il risultato (se la sostituzione stringa è vuota) è:

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

    Il contenuto del childnode è stato rimosso quando effettivamente vogliamo il childno de sé rimosso. Il risultato desiderato è:

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

    Il childnode deve essere selezionato in base all'argomento childnode.

    risposta

    24

    Mi tengo le mani in alto! Questo è un caso classico di fare la domanda sbagliata.

    Il problema è che non è possibile utilizzare xmlpoke per rimuovere un singolo nodo. Xmlpoke può essere utilizzato solo per modificare il contenuto di un nodo o attributo specifico. Non esiste un modo elegante per rimuovere un nodo figlio come da domanda utilizzando solo gli obiettivi standard Nant. È possibile eseguire utilizzando una manipolazione della stringa poco elegante utilizzando le proprietà in Nant, ma perché si desidera utilizzare?

    Il modo migliore per farlo è scrivere un semplice target Nant. Ecco quello che ho preparato in precedenza:

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

    combinare il sopra con una modifica al file NAnt.exe.config per caricare il target personalizzato e il seguente script nel file dicostruzione:

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

    Questo rimuoverà la childnode con un argomento arg con valore b da target.xm l. Che è quello che volevo davvero in primo luogo!

    +1

    Salvato un po 'di tempo. Grazie per questo! – aleemb

    +1

    Grazie per aver pubblicato la fonte. –

     Problemi correlati

    • Nessun problema correlato^_^