2011-05-03 94 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