2012-11-04 43 views
11

加入我有這樣的代碼:刪除不需要的(空)xmlns屬性通過使用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); 
} 

應該添加新<Target name="BeforeBuild" /> XML文檔。

但它也增加了一個空的xmlns=""屬性,我不想要。 (它實際上是Visual Studio中不喜歡這個屬性!)

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

我已經嘗試過這樣的代碼:

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

回答

7

檢查這些可能的解決辦法:

Powershell and csproj

Xml namespace and C# csproj

這是從第二個解決方案一種解決方法,對於OP工作:

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

感謝您的鏈接!第二種解決方案適用於我。您能否將該代碼片段插入到您的答案中?這對其他用戶會很有幫助。 – ComFreek

+0

@ComFreek:不客氣!我更新了我的答案。 – Neolisk

+4

不好的答案 - 它可能有用,但它表明了對問題原因的根本性誤解。 –

20

的的xmlns =「」命名空間(UN)宣佈已經加入,因爲你的父元素是一個命名空間,你的子元素是沒有的。如果不希望添加此名稱空間聲明,則意味着您希望子元素與其父項位於相同的名稱空間中,並且答案是在創建元素時將其放入此名稱空間中。也就是說,改變調用CreateElement(「Target」,「」)來指定正確的名稱空間。

+0

但是我沒有(直接)父元素上的任何名稱空間。只有根元素''有一個:'xmlns =「http://schemas.microsoft.com/developer/msbuild/2003」'。那麼我應該將這個值傳遞給'CreateElement()'嗎? – ComFreek

+0

我看不到足夠的代碼來確定細節(並且我討厭DOM編程),但是序列化程序添加了xmlns =「」聲明的事實非常清楚地證明父項在命名空間中(無論出於何種原因),孩子不是。 –

+0

是的,您應該爲您的新元素提供與項目根元素相同的名稱空間。否則,它將添加xmlns屬性,因爲名稱空間與父項不同。 – Ash

2

如回答邁克爾·凱,消除這種不必要的命名空間的最好辦法是創建在同一個命名空間作爲其父的新的子元素:

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

使用JavaScript

如果您正在使用JS創建XML文檔,並在父節點上聲明xmlns="XXXX"後,在子節點上獲得空白xmlns屬性,請使用JS createElementNS(namespace, nodeName)而不是createElement(nodeName)

這是假設您希望您的子節點與父級共享相同的名稱空間。在以下情況下, 'V1', 'V2' 等將分享的NS '數據'

這將是這個樣子:

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

正確的結果會是什麼樣子:

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

對戰壞的結果:

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

有了這個解決方案,你也可以單獨申報您的子節點的名稱空間。只需將nameSpace變量替換爲不同的命名空間uri字符串或另一個設置變量即可。