2012-11-04 12 views
11

mam ten kod:usunąć niechciane (pusty) atrybut xmlns dodane przez 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); 
} 

To powinny dodać nowy <Target name="BeforeBuild" /> do dokumentu XML.

Dodaje jednak także pusty atrybut xmlns="", którego nie chcę. (To rzeczywiście Visual Studio, który nie lubi tego atrybutu!)

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

Ja już próbowałem ten kod:

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

Odpowiedz

7

sprawdzić te możliwych rozwiązań:

Powershell and csproj

Xml namespace and C# csproj

Oto obejście od drugiego roztworu, który pracował dla OP:

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

Dzięki za linki! Drugie rozwiązanie sprawdziło się dla mnie.Czy możesz wstawić ten fragment kodu do swojej odpowiedzi? Będzie to bardzo pomocne dla innych użytkowników. – ComFreek

+0

@ComFreek: Nie ma za co! Zaktualizowałem swoją odpowiedź. – Neolisk

+4

Zła odpowiedź - może działać, ale sugeruje zasadnicze nieporozumienie dotyczące przyczyny problemu. –

20

xmlns = „” nazw (un) deklaracja została dodana, ponieważ elementem dominującym jest w obszarze nazw a elementem dziecko nie jest. Jeśli nie chcesz dodawać tej deklaracji przestrzeni nazw, implikacją jest to, że element podrzędny ma być w tej samej przestrzeni nazw co jej obiekt nadrzędny, a odpowiedzią jest umieszczenie go w tym obszarze nazw w momencie tworzenia elementu. To znaczy, zmienić wywołanie CreateElement ("Target", ""), aby określić poprawny obszar nazw.

+0

Ale nie mam żadnej przestrzeni nazw na (bezpośrednim) elemencie nadrzędnym. Tylko element główny '' ma jeden: 'xmlns =" ​​http://schemas.microsoft.com/developer/msbuild/2003 "'. Więc powinienem przekazać tę wartość do 'CreateElement()'? – ComFreek

+0

Nie widzę wystarczającej ilości twojego kodu, aby obliczyć szczegóły (i tak nie lubię programowania DOM), ale fakt, że serializer dodał deklarację xmlns = "" jest całkiem oczywistym dowodem, że rodzic jest w przestrzeni nazw (z jakiegokolwiek powodu), a dziecko nie. –

+0

Tak, powinieneś nadać nowemu elementowi tę samą przestrzeń nazw co element główny Projektu. W przeciwnym razie doda atrybut xmlns, ponieważ przestrzeń nazw różni się od nazwy nadrzędnej. – Ash

2

Jak odpowiedział Michael Kay, najlepszym sposobem, aby usunąć ten niechciany nazw jest tworzenie nowego elementu dzieci w tej samej przestrzeni nazw jako jego rodzica:

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

użyciu JavaScript

Jeśli używasz JS do utworzenia dokumentu XML i otrzymujesz puste atrybuty xmlns na węzłach potomnych po zadeklarowaniu xmlns="XXXX" w węźle nadrzędnym, użyj JS createElementNS(namespace, nodeName) zamiast createElement(nodeName).

Zakłada to, że chcesz, aby Twoje węzły podrzędne dzieliły ten sam obszar nazw co rodzic. W poniższym przypadku 'v1', 'v2', itp będą dzielić NS 'dane'

będzie to wyglądać mniej więcej tak:

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

poprawny wynik wyglądałby następująco:

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

Versus wyniku Źle:

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

Dzięki takiemu rozwiązaniu, można również zadeklarować oddzielny Przestrzenie nazw dla węzłów potomnych. Po prostu zastąp zmienną nameSpace innym ciągiem URI innej przestrzeni nazw lub inną zmienną zestawu.

Powiązane problemy