0

我从要转换为 .net 对象的 Web 服务中获取以下 xml:

let xmlString = "<?xml version=\"1.0\"?>
<logInResponse>
  <result>OK</result>
  <xmlLogIn>
    <session>11C0ED6F8F7288855FC73C99979A9732.TOGKE6VP9aE8abcdLXaVXg</session>
    <user>WallStreetScumbag1</user>
    <authorizations>
      <insiderTrading>true</insiderTrading>
    </authorizations>
  </xmlLogIn>
</logInResponse>"

这是我到目前为止所拥有的:

type Result(value:XmlNode) = 
    member this.Value = value.InnerText

let (|Node|Result|) (node : #System.Xml.XmlNode) =
    if node.Name = "result" then
        Result (new Result(node))
    else
        Node (seq {for x in node.ChildNodes -> x})

let extract node =
    let rec extract node =
        match node with 
        | Result(p) ->
            Seq.singleton p
        | Node(nodes) ->
            Seq.collect (fun (n) -> extract n) nodes
    extract node

let xmlDoc = new XmlDocument()
xmlDoc.LoadXml(xmlString)

//type LogIn() =
    //This is where I would create a .net object that mirrors the xml.

正如您所看到的,某些元素在不同的元素中重复,有时元素不包括可以显示的所有元素,如您在我的示例 xml 中看到的那样。这个相同的 Web 服务还将在其他类型的响应中重用许多相同的元素。是否可以使用活动模式来创建一种通用方法来反序列化我返回到对象的 xml?看起来这个 Web 服务从不使用属性来发送信息,它似乎都是元素中的元素,这可能会使这个问题变得更容易。如果我以错误的方式解决这个问题,请随时提出更好的建议。

提前致谢,

鲍勃

4

1 回答 1

0

您使用活动模式匹配不同类型节点的方法对我来说看起来不错。我可能会使用部分模式(可以Some在匹配时返回None)而不是完整模式(总是返回其中一种情况)。这允许您为正在处理的不同类型的节点编写多种模式。

let (|Result|_|) (node:#System.Xml.XmlNode) =
  if node.Name = "result" then
    Some(new Result(node))
  else
    None

在模式匹配中,您可以包含任意数量的部分模式,并使用_(通配符模式)覆盖所有剩余的情况:

match node with 
| Result(p) ->
    Seq.singleton p
| nd ->
    Seq.collect (fun (n) -> extract n) nd.ChildNodes

除此之外,我不确定 - 您示例中的结构看起来很规则,因此您不需要像 HTML 中那样处理案例(其中<a>可以嵌套在各种其他元素中)。似乎您可以将 XML 的主要部分表示为帐户列表(并使用活动模式解析所有帐户属性)。

于 2011-04-01T01:47:29.190 回答