使用 F# 反序列化 Xml
我从 Web 服务获取以下 xml,并将其转换为 .net 对象:
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 服务从不使用属性来发送信息,它似乎都是元素内的元素,这可能会使这个问题变得更容易。如果我以错误的方式处理这个问题,请随时提出更好的建议。
预先感谢,
鲍勃
I get the following xml from a web service which I want to convert into .net objects:
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>"
This is what I have so far:
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.
As you can see some elements are repeated within different elements and sometimes elements don't include all the elements that can show up as you can see in my sample xml. This same web service will also reuse many of these same elements in other types of responses. Is it possible to use active patterns to create a general way to deserialize the xml I get back into objects? It appears that this web service never uses attributes to send information, it all seems to be elements inside elements which might make this problem easier. If I am going about this the wrong way please feel free to suggest something better.
Thanks in advance,
Bob
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您使用活动模式来匹配不同类型节点的方法对我来说看起来不错。我可能会使用部分模式(当它们匹配时可以返回
Some
或None
)而不是完整模式(总是返回其中一种情况)。这允许您为正在处理的不同类型的节点编写多种模式。在模式匹配中,您可以包含任意数量的部分模式,并使用
_
(通配符模式)覆盖所有剩余的情况:除此之外,我不确定 - 您示例中的结构看起来很规则,因此您不需要像 HTML 中那样处理情况(其中
可以嵌套在各种其他元素中)。看来您可以将 XML 的主要部分表示为帐户列表(并使用活动模式解析所有帐户属性)。
Your approach to use active patterns to match different types of nodes looks good to me. I would probably use partial patterns (that can either return
Some
when they match orNone
) instead of complete patterns (that always return one of the cases). This allows you to write several patterns for different types of nodes you're handling.In the pattern matching, you can then include as many partial patterns as you like and cover all remaining cases using
_
(wildcard pattern):Other than this, I'm not sure - the structure in your example looks quite regular, so you don't need to handle cases as in HTML (where
<a>
can be nested in various other elements). It seems you can just represent the main part of XML as a list of accounts (and parse all account properties using active patterns).