2016-10-10 34 views
2

將XAttribute的命名空間添加到父XElement時意外進行修改。將System.Xml.Linq.XAttribute命名空間添加到XElement時意外修改

我有一些F#代碼看起來像這樣:

let myRoot = XElement(XName.Get("MyRoot")) 
let mychildxelement = XElement(XName.Get("MyXElement")) 
myRoot.Add(mychildxelement) 
myRoot.Add(XAttribute(XNamespace.Xmlns + "odata", "http://mynamespace")) 
let name = XNamespace.Get("odata") + myattrname 
mychildxelement.Add(XAttribute(name, "false")) 

不幸的是,當我打印出來myRoot(myRoot.ToString()),它會生成以下XML:

<MyRoot xmlns:odata="http://mynamespace"> 
    <MyXElement p3:myattrname="false" xmlns:p3="odata" /> 
</MyRoot> 

出於某種原因,它正在改變將命名空間設置爲「p3」並在XElement的根級別添加額外的名稱空間快捷方式。我真的想避免Element level xmlns。有誰知道如何避免這種情況?

+3

請提供一個[MCVE](http://stackoverflow.com/help/mcve) – CaringDev

回答

5

如果不定義它們,XML不允許使用任何前綴。當你沒有父元素或包含文檔時,名稱空間聲明的唯一位置就是元素本身。您可以自定義但前綴:

#r "System.Xml.Linq.dll" 

open System.Xml.Linq 

let myAttrName = "myattrname" 
let odata = "odata" 
let name = XNamespace.Get(odata) + myAttrName 
let myXElement = XElement(XName.Get("MyXElement")) 
myXElement.Add(XAttribute(XNamespace.Xmlns + odata, odata)) 
myXElement.Add(XAttribute(name, "false")) 

myXElement.ToString() 
// "<MyXElement xmlns:odata="odata" odata:myattrname="false" />" 

更新

當你有一個父元素,需要按照如下方式指定爲孩子命名空間(即使用的命名空間,而不是它的前綴):

#r "System.Xml.Linq.dll" 

open System.Xml.Linq 

let odata = XNamespace.Xmlns + "odata" 
let odataNS = "http://mynamespace" 
let myRoot = XElement(XName.Get("MyRoot")) 
myRoot.Add(XAttribute(odata, odataNS)) 

let myChildXElement = XElement(XName.Get("MyXElement")) 
myChildXElement.Add(XAttribute(XNamespace.Get(odataNS) + "myAttrName", "false")) 
myRoot.Add(myChildXElement) 

printfn "%A" myRoot 

其中打印(語法由SO高亮)

<MyRoot xmlns:odata="http://mynamespace"> 
    <MyXElement odata:myAttrName="false" /> 
</MyRoot> 
+0

謝謝,這有助於我理解發生了什麼。不幸的是,有一個父元素設置了xmlns,我仍然得到相同的結果。你有什麼想法我失蹤? (我更新了原始問題以包含帶有根元素的代碼) – rysama

+1

@RodYan查看更新的答案 – CaringDev

相關問題