将System.Xml.Linq.XAttribute命名空间添加到XElement时意外修改

问题描述:

将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

如果不定义它们,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