2011-05-03 93 views
4

于是,我就在下面的XML使用F# XML parsing post(从uclassify API):解析XML时,文件有xmlns属性

<?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?

谢谢

回答

3

@ dahlbyk版的作品,但一旦你有一个的XNamespace对象,你可以在F#将字符串添加到它只是作为你可以在C#中。因此,我更喜欢这种语法,因为它是一个有点接近它通常在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") 
+0

这也将是每一个如此稍快;-)。 – 2011-05-04 15:54:19

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") 
+0

不知道LINQ到XML的细节,但它很可能,这可能会稍微快:'let xnuc = XNamespace.Get(“http://api.uclassify.com/1/ResponseSchema”).GetName' – 2011-05-03 13:52:48

+0

在C#中,像'var ns = XNamespace.Get(...)和'doc.Element(ns +“uclassify”)',但是F#不能很好地与隐式转换,因此从'string'中产生'XName'的函数。 – dahlbyk 2011-05-03 15:53:04

+0

感谢您的回复,作品perfecto – jlezard 2011-05-03 17:52:09