0

我知道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>
4

3 回答 3

2

我通常做的是...

let xmlns = XNamespace.Get

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

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

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

于 2012-10-12T12:01:01.373 回答
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")
于 2012-10-12T09:21:12.207 回答
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>
于 2012-10-12T13:47:42.803 回答