2

I am searching for a method in F# to construct an xml-tree-structrue from a domain-class-model.

Guess you have some classes (types) with a parent-child-relationship like:

Container
-> Child
-> Child
-> Container
   -> Child
   -> Container
      -> Child
      -> Child
   -> Container
   -> etc.

The thing is that you cannot just simply translate this domain-tree 1:1 into XML, but you sometimes have to do slight modifications e.g.:

 "If Type(Element) = A then add additionally XYZ-Element at root"
 "If Type(Element) = B then nest B into ABC-Element"

Currently I am using XDocument + System.Xml.Linq and some recursive function over my domain-class-model which get a reference to the first XElement that has to be initialized from another function. The whole "reference thing" seems fairly not functional and I many times whished to implement it in C# rather than F#.

Can someone suggest a more functional and natural-F#ish way to solve such a task?

Peter Ittner
  • 551
  • 2
  • 13
  • 1
    The xml type provider might work better https://fsharp.github.io/FSharp.Data/library/XmlProvider.html – John Palmer Apr 30 '14 at 11:06
  • 1
    I looked at the XmlProvider. But it doesn't really fit my task because I had to provide some sample-data to get the data-provider running. And based on that sample data I could write xml. For simple structes that would be ok, but I think in my case the relationships are too complex so that I cannot always provide sample data up front. – Peter Ittner Apr 30 '14 at 13:49
  • Can you show the object hierarchy you want to serialize and the expected XML? – Daniel Apr 30 '14 at 15:10
  • Hi I figured out how to solve my task. I didn't expect to be able to modify an XDocument within a function-call. I thought in order to add sth. to a XML-tree I had to create a new one and return it. Because XDocument has mutable properties (I guess) I can add Elements within a function without doing Ref stuff... I still don't think as it to be total functional but they way I now create my XML-tree satisfies my needs. – Peter Ittner May 02 '14 at 12:39

1 Answers1

0

My Problem has been solved. For all who are interested in the code... I finally came up with sth. like this:

open System.Xml
open System.Xml.Linq

let xmlNs           = "somenamespaceurl"
let XNameStd   name = XName.Get(name, xmlNs)

let InsertIfCondition valueToInsert valueToCheck attributeName (element:XElement) =
  if valueToInsert = valueToCheck then
    element.Add(XAttribute(XNameStd attributeName,valueToInsert))


let InsertSthToTree(sth:DomainObject) (currentRoot:XElement) =
  let element = XElement(XNameStd "MyDomainElementInXML")
  currentRoot.Add(element)
  InsertIfCondition(sth.BooleanProperty,true,"IsEnabled",element)

let CreateXMLDoc =
  let someObj = DomainObject(...)
  let doc     = XDocument()
  InsertSthToTree(doc.Root)
  doc

If someone has a more functional-style of doing this I would appreciate any comments.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Peter Ittner
  • 551
  • 2
  • 13