2012-11-04 12 views
11

ho questo codice:Rimuovere indesiderati (vuoto) attributo xmlns aggiunto da appendChild

function setupProject($projectFile) { 
    [xml]$root = Get-Content $projectFile; 

    $project = $root.Project; 

    $beforeBuild = $root.CreateElement("Target", ""); 
    $beforeBuild.SetAttribute("name", "BeforeBuild"); 
    $beforeBuild.RemoveAttribute("xmlns"); 
    $project.AppendChild($beforeBuild); 

    $root.Save($projectFile); 
} 

E dovrebbe aggiungere un nuovo <Target name="BeforeBuild" /> al documento XML.

Ma aggiunge anche un attributo vuoto xmlns="" che non desidero. (In realtà è Visual Studio, che non ama questo attributo!)

<Target name="BeforeBuild" xmlns="" /> 

Ho già provato questo codice:

$beforeBuild.RemoveAttribute("xmlns"); 
$project.AppendChild($beforeBuild); 
$beforeBuild.RemoveAttribute("xmlns"); 

risposta

7

controllare queste possibili soluzioni:

Powershell and csproj

Xml namespace and C# csproj

Ecco una soluzione dalla seconda soluzione che ha funzionato per OP:

$content = [xml] $content.OuterXml.Replace(" xmlns=`"`"", "") 
$content.Save($_.FullName); 
+1

Grazie per i collegamenti! La seconda soluzione ha funzionato per me.Potresti inserire lo snippet di codice nella tua risposta? Sarà molto utile per gli altri utenti. – ComFreek

+0

@ComFreek: siete i benvenuti! Ho aggiornato la mia risposta. – Neolisk

+4

Risposta errata: potrebbe funzionare, ma suggerisce un malinteso fondamentale sulla causa del problema. –

20

Le xmlns = "" (un) dichiarazione dello spazio dei nomi è stato aggiunto perché il vostro elemento principale è in uno spazio dei nomi e il vostro elemento figlio non lo è. Se non si desidera aggiungere questa dichiarazione dello spazio dei nomi, l'implicazione è che si desidera che l'elemento figlio si trovi nello stesso spazio dei nomi del suo genitore e la risposta è di inserirlo in questo spazio dei nomi nel momento in cui si crea l'elemento. Cioè, cambia la chiamata CreateElement ("Target", "") per specificare lo spazio dei nomi corretto.

+0

Ma non ho alcun namespace sull'elemento padre (diretto). Solo l'elemento radice '' ha uno: 'xmlns =" ​​http://schemas.microsoft.com/developer/msbuild/2003 "'. Quindi dovrei passare questo valore a 'CreateElement()'? – ComFreek

+0

Non riesco a vedere abbastanza codice per elaborare i dettagli (e odio comunque la programmazione DOM), ma il fatto che il serializzatore abbia aggiunto una dichiarazione xmlns = "" è una prova abbastanza chiara che il genitore si trova in uno spazio dei nomi (per qualsiasi motivo) e il bambino non lo è. –

+0

Sì, dovresti assegnare al nuovo elemento lo stesso spazio dei nomi dell'elemento radice del progetto. Altrimenti, aggiungerà l'attributo xmlns perché lo spazio dei nomi è diverso dal genitore. – Ash

2

Come risposto da Michael Kay, il modo migliore per rimuovere questo spazio dei nomi indesiderato sta creando il nuovo elemento figlio nello stesso spazio dei nomi come il suo genitore:

function setupProject($projectFile) { 
    [xml]$root = Get-Content $projectFile; 

    $project = $root.Project; 

    //UPDATE THIS LINE $beforeBuild = $root.CreateElement("Target", ""); 
    $beforeBuild = $root.CreateElement("Target", $project.NamespaceURI); 
    $beforeBuild.SetAttribute("name", "BeforeBuild"); 
    $beforeBuild.RemoveAttribute("xmlns"); 
    $project.AppendChild($beforeBuild); 

    $root.Save($projectFile); 
} 
0

utilizzando JavaScript

Se si sta utilizzando JS per creare un documento XML e ottengono attributi xmlns vuoti sui nodi figlio dopo aver dichiarato xmlns="XXXX" sul nodo padre, utilizzare JS createElementNS(namespace, nodeName) anziché createElement(nodeName).

Si presume che si desideri che i nodi figlio condividano lo stesso spazio dei nomi del genitore. Nel caso di sotto 'v1', 'v2', ecc condivideranno le NS di 'dati'

Sarebbe simile a questa:

let data = someArray; 
let nameSpace = 'XXX'; 
let doc = "<?xml version='1.0' encoding='utf-8' ?><data xmlns='XXXX'></data>"; 
let parser = new DOMParser(); 
let xml = parser.parseFromString(doc, "text/xml"); 

for (let i = 0; i < data.length; i++) { 
    let node = xml.createElementNS(nameSpace , "v" + (i + 1)); 
    $(node).text(data[i]); 
    let elements = xml.getElementsByTagName("data"); 
    elements[0].appendChild(node); 
} 

risultato corretto sarebbe simile:

<?xml version='1.0' encoding='utf-8' ?> 
<data xmlns='XXXX'> 
    <v1></v1> 
    <v2></v2> 
</data> 

Versus risultato BAD:

<?xml version='1.0' encoding='utf-8' ?> 
<data xmlns='XXXX'> 
    <v1 xmlns=""></v1> 
    <v2 xmlns=""></v2> 
</data> 

Con questa soluzione, si potrebbe anche dichiarare separata Namespace per i nodi figlio. Sostituisci semplicemente la variabile nameSpace con una stringa uri diversa dello spazio dei nomi o un'altra variabile impostata.