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

By on 11/28/2007 1:43 PM ()

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>
By on 11/29/2007 5:08 AM ()

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

By on 11/30/2007 12:16 PM ()

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!

By on 12/18/2007 8:03 AM ()

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

By on 12/18/2007 4:30 PM ()

Hi Don,

This is excellent, Thanks!

regards

By on 12/19/2007 12:21 AM ()

Wow, such a fast reply!

Thanks, Don!

By on 11/28/2007 1:53 PM ()
IntelliFactory Offices 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