当文件具有xmlns属性时,在F#中解析xml

时间:2011-05-03 13:06:59

标签: xml f# xml-namespaces

所以我尝试在以下xml上使用F# XML parsing post(来自uclassify API):

<?xml version="1.0" encoding="UTF-8" ?> 
<uclassify xmlns="http://api.uclassify.com/1/ResponseSchema" version="1.01"> 
    <status success="true" statusCode="2000"/> 
    <readCalls> 
    <classify id="cls1"> 
        <classification textCoverage="1"> 
            <class className="happy" p="0.912929"/> 
            <class className="upset" p="0.0870707"/> 
        </classification> 
    </classify> 
    </readCalls> 
</uclassify>

代码如下:

let doc  = 
    Xdocument.Load file
doc.Element(xn "uclassify")
   .Element(xn "readCalls")
   .Element(xn "classify")
   .Element(xn "classification")
   .Element(xn "class").Attribute(xn "p")

这不起作用!!!似乎无法完成解析。然而,删除属性xmlns="http://api.uclassify.com/1/ResponseSchema" version="1.01"会使其有效:

let doc  = 
    Xdocument.Load file
    let test = IO.File.ReadAllText(file).Replace("xmlns=\"http://api.uclassify.com/1/ResponseSchema\" version=\"1.01\"","")
    XDocument.Parse(test)

doc.Element(xn "uclassify")
   .Element(xn "readCalls")
   .Element(xn "classify")
   .Element(xn "classification")
   .Element(xn "class").Attribute(xn "p")

请注意,此问题似乎与Why must I remove xmlns attribute ...有关。所以问题是为什么我必须删除xmlns属性?我应该用什么来解析具有xmlns属性的xml?

谢谢

2 个答案:

答案 0 :(得分:3)

@ dahlbyk的版本有效,但是一旦你有了一个XNamespace对象,就可以像在C#中一样在F#中添加一个字符串。因此,我更喜欢这种语法,因为它更接近于通常在C#中完成的方式:

let xn = XName.Get
let xmlns = XNamespace.Get

let ns = xmlns "http://api.uclassify.com/1/ResponseSchema"

doc.Element(ns + "uclassify")
   .Element(ns + "readCalls")
   .Element(ns + "classify")
   .Element(ns + "classification")
   .Element(ns + "class")
   .Attribute(xn "p")

答案 1 :(得分:2)

您需要使用其命名空间引用元素:

let xn (tag:string) = XName.Get(tag)
let xnuc (tag:string) = XName.Get(tag, "http://api.uclassify.com/1/ResponseSchema")

doc.Element(xnuc "uclassify")
   .Element(xnuc "readCalls")
   .Element(xnuc "classify")
   .Element(xnuc "classification")
   .Element(xnuc "class")
   .Attribute(xn "p")