What you tried is exactly how it _should_ be, i.e. it's a known limitation.
For now you use this:
1 2 3 4 5 6 7 8 9 10 11 12 13
type isinInfo = { [<XmlAttribute("Symbol")>] symbol: string; [<XmlAttribute("FaceValue")>] faceValue: float; [<XmlAttribute("MarketLot")>] marketLot: int; [<XmlArray("Exchanges"); XmlArrayItem("Exchange", (type exchangeInfo))>] exchangeList: ResizeArray<xchangeInfo>};;
Don
Hi,
I'm still on the translation. The typeof trick works fine, but there is another problem: all fields and types are automatically exposed by XmlSerializer, i.e. they are exposed with XmlAttribute as expected, but moreover they also export themselves with their type names and field names as XML elements again, which is unexpected.
Here is my full translation. This simple program first deserializes a Xml document to some data structure based on XmlAttribute annotatations, then serialize the data structure to a new Xml document based on the same configuration. Ideally, the new Xml should be equivalent to the old one in semantics.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
open System.IO;; open System.Xml.Serialization;; type exchangeInfo = class [<XmlAttribute("Code")>] val mutable exchangeCode: string [<XmlAttribute("ScripCode")>] val mutable scripCode: string new() = { exchangeCode = null; scripCode = null } end;; type isinInfo = class [<XmlAttribute("Symbol")>] val mutable symbol: string [<XmlAttribute("FaceValue")>] val mutable faceValue: float [<XmlAttribute("MarketLot")>] val mutable marketLot: int [<XmlArray("Exchanges"); XmlArrayItem("Exchange", (type exchangeInfo))>] val mutable exchangeList: ResizeArray<exchangeInfo> new() = { symbol = null; faceValue = 0.; marketLot = 0; exchangeList = ResizeArray.of_list [] } end;; [<XmlRoot("ISINMaster")>] type isinDataStore = class [<XmlArray("ISINS"); XmlArrayItem("ISIN", (type isinInfo))>] val mutable isinStore: isinInfo ResizeArray new() = { isinStore = ResizeArray.of_list [] } end;; let isinPath = @"ISINMaster.xml";; let newisinPath = @"NewISINMaster.xml";; use xmlDoc = new StreamReader(isinPath) in let isinXml = XmlSerializer(typeof<isinDataStore>) in let dataStore = isinXml.Deserialize(xmlDoc) in use newXmlDoc = new StreamWriter(newisinPath) in isinXml.Serialize(newXmlDoc, dataStore);;
The test input Xml file: ISINMaster.xml
1 2 3 4 5 6 7 8 9
<ISINMaster> <ISINS> <ISIN Symbol="MSFT" FaceValue="10" MarketLot="5"> <Exchanges> <Exchange Code="NASDAQ" ScripCode="MSFT.O" /> </Exchanges> </ISIN> </ISINS> </ISINMaster>
The output Xml file: NewISINMaster.xml. (Note that except for those superfluours Xml elements for each field and type, other things are actually working as expected.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
<?xml version="1.0" encoding="utf-8"?> <ISINMaster xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <_isinStore> <isinInfo Symbol="MSFT" FaceValue="10" MarketLot="5"> <_symbol>MSFT</_symbol> <_faceValue>10</_faceValue> <_marketLot>5</_marketLot> <_exchangeList> <exchangeInfo Code="NASDAQ" ScripCode="MSFT.O"> <_exchangeCode>NASDAQ</_exchangeCode> <_scripCode>MSFT.O</_scripCode> </exchangeInfo> </_exchangeList> <Exchanges> <Exchange Code="NASDAQ" ScripCode="MSFT.O"> <_exchangeCode>NASDAQ</_exchangeCode> <_scripCode>MSFT.O</_scripCode> </Exchange> </Exchanges> </isinInfo> </_isinStore> <ISINS> <ISIN Symbol="MSFT" FaceValue="10" MarketLot="5"> <_symbol>MSFT</_symbol> <_faceValue>10</_faceValue> <_marketLot>5</_marketLot> <_exchangeList> <exchangeInfo Code="NASDAQ" ScripCode="MSFT.O"> <_exchangeCode>NASDAQ</_exchangeCode> <_scripCode>MSFT.O</_scripCode> </exchangeInfo> </_exchangeList> <Exchanges> <Exchange Code="NASDAQ" ScripCode="MSFT.O"> <_exchangeCode>NASDAQ</_exchangeCode> <_scripCode>MSFT.O</_scripCode> </Exchange> </Exchanges> </ISIN> </ISINS> </ISINMaster>
Hi d2bg,
Get F# 1.9.3.7 from [link:blogs.msdn.com].
Then use the "field:" attribute target:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
#light open System.IO;; open System.Xml.Serialization type exchangeInfo = class [<field: XmlAttribute("Code")>] val mutable exchangeCode: string [<field: XmlAttribute("ScripCode")>] val mutable scripCode: string new() = { exchangeCode = null; scripCode = null } end type isinInfo = class [<field: XmlAttribute("Symbol")>] val mutable symbol: string [<field: XmlAttribute("FaceValue")>] val mutable faceValue: float [<field: XmlAttribute("MarketLot")>] val mutable marketLot: int [<field: XmlArray("Exchanges"); field: XmlArrayItem("Exchange", (type exchangeInfo))>] val mutable exchangeList: ResizeArray<exchangeInfo> new() = { symbol = null; faceValue = 0.; marketLot = 0; exchangeList = ResizeArray.of_list [] } end [<XmlRoot("ISINMaster")>] type isinDataStore = class [<field: XmlArray("ISINS"); field: XmlArrayItem("ISIN", (type isinInfo))>] val mutable isinStore: isinInfo ResizeArray new() = { isinStore = ResizeArray.of_list [] } end
I believe this solves your problem, though it was hard for me to check if the two files were equivalent in semantics.
Cheers!
don
Hi Don,
Sorry for missing your post for such a long time. I tested the example, the anoying underscores are gone. But maybe I miss used the new feature, there is still a problem left, the object fields are also exported on plus to the expected attributes.
Here is the testing input XML file: ISINMaster.xml.
<ISINMaster>
<ISINS>
<ISIN ISINCode="US5949181045"
Symbol="MSFT"
FaceValue="10"
MarketLot="5"
Status="Active" >
<Exchanges>
<Exchange Code="NASDAQ"
ScripCode="MSFT.O" />
<Exchange Code="NYSE"
ScripCode="MSFT.N" />
</Exchanges>
</ISIN>
</ISINS>
</ISINMaster>
Te output XML file NewISINMaster.xml is expected to have a similar apperence as the input one. The F# version is almost correct, except that all field names are also exported automatically. Here is some segment from the output:
<Exchanges>
<Exchange Code="NASDAQ" ScripCode="MSFT.O">
<exchangeCode>NASDAQ</exchangeCode>
<scripCode>MSFT.O</scripCode>
</Exchange>
<Exchange Code="NYSE" ScripCode="MSFT.N">
<exchangeCode>NYSE</exchangeCode>
<scripCode>MSFT.N</scripCode>
</Exchange>
</Exchanges>
Here is the C# version's full output for reference.
<?xml version="1.0" encoding="utf-8"?>
<ISINMaster xmlns:xsi="[link:www.w3.org] xmlns:xsd="[link:www.w3.org]
<ISINS>
<ISIN Symbol="MSFT" FaceValue="10" MarketLot="5">
<Exchanges>
<Exchange Code="NASDAQ" ScripCode="MSFT.O" />
<Exchange Code="NYSE" ScripCode="MSFT.N" />
</Exchanges>
</ISIN>
</ISINS>
</ISINMaster>
Thanks!
OK, I see: since F# generates both a property and a field, you have to "ignore" one and attach the attributes to the other (it doesn't matter which way around it is). See below.
1 2 3 4 5 6 7 8 9 10 11
type exchangeInfo = class [<field: XmlAttribute("Code"); property: XmlIgnoreAttribute>] val mutable exchangeCode: string [<field: XmlAttribute("ScripCode"); property: XmlIgnoreAttribute>] val mutable scripCode: string new() = { exchangeCode = null; scripCode = null } end
Using this I finally got what I think you expect:
<?xml version="1.0" encoding="utf-8"?>
<ISINMaster xmlns:xsi="[link:www.w3.org]" xmlns:xsd="[link:www.w3.org]
<ISINS>
<ISIN Symbol="MSFT" FaceValue="10" MarketLot="5">
<Exchanges>
<Exchange Code="NASDAQ" ScripCode="MSFT.O" />
</Exchanges>
</ISIN>
</ISINS>
</ISINMaster>
don
Hi Don,
This is excellent, Thanks!
regards
Wow, such a fast reply!
Thanks, Don!
Topic tags
- f# × 3705
- websharper × 1897
- compiler × 286
- functional × 201
- ui next × 139
- c# × 121
- classes × 97
- web × 97
- .net × 84
- book × 84
- async × 76
- ui.next × 67
- bug × 54
- core × 49
- website × 49
- server × 45
- parallel × 43
- ui × 43
- enhancement × 41
- parsing × 41
- testing × 41
- trywebsharper × 41
- typescript × 37
- html × 35
- javascript × 35
- owin × 35
- asynchronous × 30
- monad × 28
- ocaml × 28
- tutorial × 27
- warp × 27
- haskell × 26
- sitelet × 25
- linq × 22
- workflows × 22
- wpf × 20
- fpish × 19
- introduction × 19
- silverlight × 19
- sitelets × 19
- monodevelop × 17
- rpc × 17
- suave × 17
- piglets × 16
- collections × 15
- feature request × 15
- jquery × 15
- templates × 15
- getting started × 14
- pipeline × 14
- kendoui × 13
- reactive × 12
- 4.1.0.171 × 11
- monads × 11
- opinion × 10
- 4.0.190.100-rc × 9
- deployment × 9
- fixed × 9
- formlets × 9
- in × 9
- json × 9
- plugin × 9
- proposal × 9
- scheme × 9
- solid × 9
- basics × 8
- concurrent × 8
- highcharts × 8
- how-to × 8
- python × 8
- 4.1.1.175 × 7
- complexity × 7
- documentation × 7
- visual studio × 7
- 4.1.2.178 × 6
- lisp × 6
- real-world × 6
- released in 4.0.192.103-rc × 6
- remoting × 6
- resources × 6
- scala × 6
- websharper ui.next × 6
- workshop × 6
- xaml × 6
- 4.0.193.110 × 5
- 4.2.3.236 × 5
- aspnetmvc × 5
- authentication × 5
- azure × 5
- bootstrap × 5
- conference × 5
- dsl × 5
- formlet × 5
- java × 5
- list × 5
- metaprogramming × 5
- ml × 5
- released in Zafir.4.0.188.91-beta10 × 5
- sql × 5
- visualstudio × 5
- websharper.forms × 5
- zafir × 5
- 4.0.192.106 × 4
- 4.0.195.127 × 4
- 4.1.0.38 × 4
- 4.2.1.86 × 4
- 4.2.6.118 × 4
- css × 4
- example × 4
- extensions × 4
- fsi × 4
- fsx × 4
- html5 × 4
- jqueryui × 4
- lift × 4
- reflection × 4
- remote × 4
- rest × 4
- spa × 4
- teaching × 4
- template × 4
- websocket × 4
- wontfix × 4
- 4.0.196.147 × 3
- 4.1.0.34 × 3
- 4.1.6.207 × 3
- 4.2.1.223-beta × 3
- 4.2.11.258 × 3
- 4.2.4.114 × 3
- 4.2.4.247 × 3
- 4.2.5.115 × 3
- 4.2.6.253 × 3
- 4.2.9.256 × 3
- ajax × 3
- alt.net × 3
- aml × 3
- asp.net mvc × 3
- canvas × 3
- cloudsharper × 3
- compilation × 3
- database × 3
- erlang × 3
- events × 3
- extension × 3
- file upload × 3
- forums × 3
- inline × 3
- issue × 3
- kendo × 3
- macro × 3
- mono × 3
- msbuild × 3
- mvc × 3
- pattern × 3
- piglet × 3
- released in Zafir.4.0.187.90-beta10 × 3
- svg × 3
- type provider × 3
- view × 3
- 4.1.1.64 × 2
- 4.1.5.203 × 2
- 4.1.7.232 × 2
- 4.2.10.257 × 2
- 4.2.3.111 × 2
- 4.2.5.249 × 2
- android × 2
- asp.net × 2
- beginner × 2
- blog × 2
- chart × 2
- client × 2
- client server app × 2
- clojure × 2
- computation expressions × 2
- constructor × 2
- corporate × 2
- courses × 2
- cufp × 2
- d3 × 2
- debugging × 2
- direct × 2
- discriminated union × 2
- docs × 2
- elm × 2
- endpoint × 2
- endpoints × 2
- enterprise × 2
- entity framework × 2
- event × 2
- f# interactive × 2
- fable × 2
- flowlet × 2
- formdata × 2
- forms × 2
- fsc × 2
- google maps × 2
- hosting × 2
- http × 2
- https × 2
- iis 8.0 × 2
- install × 2
- interactive × 2
- interface × 2
- iphone × 2
- iteratee × 2
- jobs × 2
- jquery mobile × 2
- keynote × 2
- lens × 2
- lenses × 2
- linux × 2
- listmodel × 2
- mac × 2
- numeric × 2
- oauth × 2
- obfuscation × 2
- offline × 2
- oop × 2
- osx × 2
- packaging × 2
- pattern matching × 2
- performance × 2
- pipelines × 2
- q&a × 2
- quotation × 2
- reference × 2
- released in Zafir.4.0.185.88-beta10 × 2
- rx × 2
- script × 2
- security × 2
- self host × 2
- seq × 2
- sockets × 2
- stm × 2
- tcp × 2
- trie × 2
- tutorials × 2
- type × 2
- url × 2
- var × 2
- websharper.charting × 2
- websharper4 × 2
- websockets × 2
- wig × 2
- xna × 2
- zh × 2
- .net interop × 1
- 2012 × 1
- 4.0.194.126 × 1
- 4.1.3.184 × 1
- 4.1.4.189 × 1
- 4.2.0.214-beta × 1
- 4.2.12.259 × 1
- 4.2.2.231-beta × 1
- 4.2.8.255 × 1
- Canvas Sample Example × 1
- DynamicStyle Animated Style × 1
- Fixed in 4.0.190.100-rc × 1
- Released in Zafir.UI.Next.4.0.169.79-beta10 × 1
- SvgDynamicAttribute × 1
- WebComponent × 1
- abstract class × 1
- accumulator × 1
- active pattern × 1
- actor × 1
- addin × 1
- agents × 1
- aggregation × 1
- agile × 1
- alter session × 1
- animation × 1
- anonymous object × 1
- apache × 1
- api × 1
- appcelerator × 1
- architecture × 1
- array × 1
- arrays × 1
- asp.net 4.5 × 1
- asp.net core × 1
- asp.net integration × 1
- asp.net mvc 4 × 1
- asp.net web api × 1
- aspnet × 1
- ast × 1
- attributes × 1
- authorization × 1
- b-tree × 1
- back button × 1
- badimageformatexception × 1
- bash script × 1
- batching × 1
- binding-vars × 1
- bistro × 1
- body × 1
- bundle × 1
- camtasia studio × 1
- cas protocol × 1
- charts × 1
- clarity × 1
- class × 1
- cli × 1
- clipboard × 1
- clojurescript × 1
- closures × 1
- cloud × 1
- cms × 1
- coding diacritics × 1
- color highlighting × 1
- color zones × 1
- combinator × 1
- combinators × 1
- compile × 1
- compile code on server × 1
- config × 1
- confirm × 1
- content × 1
- context × 1
- context.usersession × 1
- continuation-passing style × 1
- coords × 1
- cordova × 1
- cors × 1
- coursera × 1
- cross-domain × 1
- csla × 1
- current_schema × 1
- custom content × 1
- data × 1
- data grid × 1
- datetime × 1
- debug × 1
- declarative × 1
- delete × 1
- devexpress × 1
- dhtmlx × 1
- dictionary × 1
- directattribute × 1
- disqus × 1
- distance × 1
- do binding × 1
- doc elt ui.next upgrade × 1
- docker × 1
- dojo × 1
- dol × 1
- dom × 1
- domain × 1
- du × 1
- duf-101 × 1
- dynamic × 1
- eastern language × 1
- eclipse × 1
- edsl × 1
- em algorithm × 1
- emacs × 1
- emotion × 1
- enums × 1
- error × 1
- etw × 1
- euclidean × 1
- eventhandlerlist × 1
- examples × 1
- ext js × 1
- extension methods × 1
- extra × 1
- facet pattern × 1
- failed to translate × 1
- fake × 1
- fantomas × 1
- fear × 1
- float × 1
- form × 1
- form-data × 1
- forum × 1
- fp × 1
- frank × 1
- fsdoc × 1
- fsharp × 1
- fsharp.core × 1
- fsharp.powerpack × 1
- fsharpx × 1
- fsunit × 1
- function × 1
- functional style × 1
- game × 1
- games × 1
- gc × 1
- generic × 1
- geometry × 1
- getlastwin32error × 1
- getting-started × 1
- google × 1
- google.maps × 1
- grid × 1
- group × 1
- guide × 1
- hash × 1
- headers × 1
- hello world example × 1
- heroku × 1
- highchart × 1
- history × 1
- how to × 1
- html-templating × 1
- http405 × 1
- httpcontext × 1
- hubfs × 1
- i18n × 1
- ie 8 × 1
- if-doc × 1
- iis × 1
- image × 1
- images × 1
- inheritance × 1
- initialize × 1
- input × 1
- install "visual studio" × 1
- installer × 1
- int64 × 1
- interfaces × 1
- internet explorer × 1
- interop × 1
- interpreter × 1
- io × 1
- iobservable × 1
- ios × 1
- iot × 1
- ipad × 1
- isomorphic × 1
- javascript optimization × 1
- javascript semanticui resources × 1
- jquery-plugin × 1
- jquery-ui × 1
- jquery-ui-datepicker × 1
- js × 1
- kendo datasource × 1
- kendochart × 1
- kendoui compiler × 1
- knockout × 1
- l10n × 1
- learning × 1
- library × 1
- libs × 1
- license × 1
- licensing × 1
- lineserieszonescfg × 1
- local setting × 1
- localization × 1
- logging × 1
- loop × 1
- macros × 1
- mailboxprocessor × 1
- mapping × 1
- maps × 1
- markerclusterer × 1
- markup × 1
- marshal × 1
- math × 1
- mathjax × 1
- message × 1
- message passing × 1
- message-passing × 1
- meta × 1
- metro style × 1
- micro orm × 1
- minimum-requirements × 1
- mix × 1
- mobile installation × 1
- mod_mono × 1
- modal × 1
- module × 1
- mouseevent × 1
- mouseposition × 1
- multidimensional × 1
- multiline × 1
- multithreading × 1
- mysql × 1
- mysqlclient × 1
- nancy × 1
- native × 1
- nested × 1
- nested loops × 1
- node × 1
- nunit × 1
- object relation mapper × 1
- object-oriented × 1
- om × 1
- onboarding × 1
- onclick × 1
- optimization × 1
- option × 1
- orm × 1
- os x × 1
- output-path × 1
- override × 1
- paper × 1
- parameter × 1
- persistence × 1
- persistent data structure × 1
- phonegap × 1
- pola × 1
- post × 1
- powerpack × 1
- prefix tree × 1
- principle of least authority × 1
- privacy × 1
- private × 1
- profile × 1
- programming × 1
- project × 1
- project euler × 1
- projekt_feladat × 1
- protected × 1
- provider × 1
- proxy × 1
- ptvs × 1
- public × 1
- pure f# × 1
- purescript × 1
- qna × 1
- quant × 1
- query sitelet × 1
- question × 1
- quotations × 1
- range × 1
- raphael × 1
- razor × 1
- rc × 1
- reactjs × 1
- real-time × 1
- ref × 1
- region × 1
- released in 4.0.190.100-rc × 1
- reporting × 1
- responsive design × 1
- rest api × 1
- rest sitelet × 1
- restful × 1
- round table × 1
- router × 1
- routing × 1
- rpc reverseproxy × 1
- runtime × 1
- sales × 1
- sample × 1
- sampleapp × 1
- scriptcs × 1
- scripting × 1
- search × 1
- self hosted × 1
- semanticui × 1
- sequence × 1
- serialisation × 1
- service × 1
- session-state × 1
- sharepoint × 1
- signals × 1
- sitelet website × 1
- sitelet.protect × 1
- sitlets × 1
- slickgrid × 1
- source code × 1
- sqlentityconnection × 1
- ssl × 1
- standards × 1
- static content × 1
- stickynotes × 1
- streamreader × 1
- stress × 1
- strong name × 1
- structures × 1
- submitbutton × 1
- subscribe × 1
- svg example html5 websharper.ui.next × 1
- sweetalert × 1
- system.datetime × 1
- system.reflection.targetinvocationexception × 1
- table storage × 1
- targets × 1
- tdd × 1
- templates ui.next × 1
- templating × 1
- text parsing × 1
- three.js × 1
- time travel × 1
- tls × 1
- tooltip × 1
- tracing × 1
- tsunamiide × 1
- turkish × 1
- twitter-bootstrap × 1
- type erasure × 1
- type inference × 1
- type providers × 1
- type-providers × 1
- typeprovider × 1
- ui next forms × 1
- ui-next × 1
- ui.next jqueryui × 1
- ui.next charting × 1
- ui.next formlets × 1
- ui.next forms × 1
- ui.next suave visualstudio × 1
- ui.next templating × 1
- unicode × 1
- unittest client × 1
- upload × 1
- usersession × 1
- validation × 1
- vb × 1
- vb.net × 1
- vector × 1
- view.map × 1
- visal studio × 1
- visual f# × 1
- visual studio 11 × 1
- visual studio 2012 × 1
- visual studio shell × 1
- vs2017 compiler zafir × 1
- vsix × 1
- web api × 1
- web-scraping × 1
- webapi × 1
- webcomponents × 1
- webforms × 1
- webgl × 1
- webrtc × 1
- webshaper × 1
- websharper async × 1
- websharper codemirror × 1
- websharper f# google × 1
- websharper forms × 1
- websharper reactive × 1
- websharper rpc × 1
- websharper sitelets routing × 1
- websharper warp × 1
- websharper-interface-generator × 1
- websharper.chartsjs × 1
- websharper.com × 1
- websharper.exe × 1
- websharper.owin × 1
- websharper.ui.next × 1
- websharper.ui.next jquery × 1
- websockets iis × 1
- why-websharper × 1
- windows 7 × 1
- windows 8 × 1
- windows-phone × 1
- winrt × 1
- www.grabbitmedia.com × 1
- xamarin × 1
- xml × 1
- yeoman × 1
- yield × 1
- zafir beta × 1
- zafir websharper4 × 1
- zarovizsga × 1
![]() |
Copyright (c) 2011-2012 IntelliFactory. All rights reserved. Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy |
Built with WebSharper |
I'm translating some C# code into F#, which make use of XML serialization attributes and the XmlSerializer class to (de)serialize data types.
The original C# code segment looks like:
My direct translation doesn't work:
The error was spotted at the "XmlArray" "XmlArrayItem" line. The messages said "invalid custom attribute value (not a constant): typeof@[exchangeInfo]`.". Spliting them into two seperate clauses didn't help.
Could anyone tell me what's the correct translation please?