如何向XElement添加名称空间前缀

时间:2012-10-12 09:06:01

标签: xml f#

我知道http://msdn.microsoft.com/en-us/library/bb387069.aspx。我已经阅读了这些示例文章。但是在F#中,String转换为XName会遇到一些麻烦。我尝试使用的一些代码:

let ( !! ) : string -> XName = XName.op_Implicit


> XElement(!!"tmp:" + !!"root", !!"Content");; 
stdin(9,21): error FS0001: The type 'XName' does not support any operators named '+'

> XElement(!!("tmp:" + "root"), !!"Content");;
System.Xml.XmlException: The ':' character, hexadecimal value 0x3A, cannot be included in a name.

> XElement("tmp" + "root", "Content");;   
The type 'string' is not compatible with the type 'XName'

我想要的是什么:

<tmp:root>Content</tmp:root>

UPD: 我只希望在标记之前使用前缀命名空间,如:

<tmp:root>Content</tmp:root>

没有类似的东西:

> let ns = XNamespace.Get "http://tmp.com/";; 

val ns : XNamespace = http://tmp.com/

> let xe = XElement(ns + "root", "Content");;

val xe : XElement = <root xmlns="http://tmp.com/">Content</root>

3 个答案:

答案 0 :(得分:2)

我通常做的是......

let xmlns = XNamespace.Get

let ns = xmlns "http://my.namespace/"

XElement(ns + "root", "Content")

此外,我倾向于不担心在字符串输出中格式化名称空间的两种不同方式之间的区别。这对XML解析器来说意味着同样的事情。

答案 1 :(得分:1)

我要做的是为每个命名空间定义一个额外的函数:

let (!!) = XName.op_Implicit

let tmp = 
    let ns = XNamespace.op_Implicit "www.temp.com"
    fun n -> XNamespace.op_Addition (ns, n)

XElement (tmp "root", "Content")

或者,您可以创建一个处理名称中的“:”的函数:

let xn (name : String) =
    match name.IndexOf ':' with
    | -1 -> XName.op_Implicit name
    |  i -> XNamespace.op_Addition (XNamespace.Get (name.Substring (0, i)), name.Substring (i + 1))

XElement (xn "tmp:test", "Content")

答案 2 :(得分:0)

您需要为此添加命名空间才能生效。 尝试这样的事情:

#r "System.Xml.Linq.dll";;
open System.Xml.Linq

let ns = "tmp" |> XNamespace.Get
let ( !! ) : string -> XName = XName.op_Implicit

let rt = !!("blank")

let urlset = new XElement(rt,
                          new XAttribute(XNamespace.Xmlns + "tmp",ns ),
                          new XElement( ns + "root","Content"))

输出:

val urlset : XElement =
<blank xmlns:tmp="tmp">
   <tmp:root>Content</tmp:root>
</blank>