none
Dataset - I'm looking for a good solution with business object RRS feed

  • Question

  • Hello Michael,
    .
    I have received an XML file from my client as it should look.
    Now I have to generate a result file via my program and put it under 2018-12-17-Result.XML on the server.
    There are between 100 and 500 panels in the XML file. Side 1 and 2 between 5 and 20 positions.
    >You mentioned using LINQ and XDocument, that becomes easier.
    Would you prefer that?
     
    >if you want to do anything more complex then you should probably switch to a *business object* that
    >can better enforce these rules. The relations the dataset is setting up aren't really business
    >relations but those needed to make the XML valid. This results in *extra relations* that aren't
    >really needed. It is pretty straightforward to generate XML read/write code that can write
    >business objects and would eliminate the need for you to mix data manipulation
    >(e.g. adding rows) with the XML/Dataset requirements
    Can you please show me the business objects?
    Maybe that's the better way, if I know how it works.
    If you show me in this forum, I thank you in advance.
    Greetings Markus

    Monday, December 17, 2018 5:43 PM

Answers

  • It will ultimately depend upon what you're doing. For simple changes XDocument is probably the easiest. I provided an example of how to do that in your other post. You can rather easily add and query XML using it. 

    If all the XML structures are different but return effectively the same data then I'd switch to business objects to work with and use separate "Document" classes to handle serializing/deserializing XML. Depending upon the format you can use the built in XmlSerializer to handle this automatically. But the builtin serializer requires certain rules be followed. If you don't have control over the XML then it will be harder to use. In that case you'll need to serialize by hand. Again though you could use business objects for your manipulation and then use XDocument to read/write. Here's a very simple example (note that the XmlSerializer can do this structure as well) if you wanted to go that route.

    class Program
    {
        static void Main ( string[] args )
        {
            var shapes = new[]
            {
                new Shape() {
                    Name = "S1",
                    Panels = new []
                    {
                        new Panel()
                        {
                            Sides = new []
                            {
                                new Side()
                                {
                                    Positions = new []
                                    {
                                        new Position() { X = 10, Y = 10 },
                                        new Position() { X = 20, Y = 20 }
                                    }
                                },
                                new Side()
                                {
                                    Positions = new[]
                                    {
                                        new Position() { X = 30, Y = 30 }
                                    }
                                }
                            }
                        }
                    }
                }
            };
    
            //Save to XML
            var doc = new ShapeDocument();
            doc.Shapes = shapes;
            doc.Save("shapes.xml");
    
            //Read it back
            doc = new ShapeDocument();
            doc.Load("shapes.xml");
    
            var newShapes = doc.Shapes;
        }
    }
    
    public class Shape
    {
        public string Name { get; set; }
    
        public IEnumerable<Panel> Panels { get; set; }
    }
    
    public class Panel
    {
        public IEnumerable<Side> Sides { get; set; }
    }
    
    public class Side
    {
        public IEnumerable<Position> Positions { get; set; }
    }
    
    public class Position
    {
        public double X { get; set; }
        public double Y { get; set; }
    }
    
    public class ShapeDocument
    {
        public IEnumerable<Shape> Shapes { get; set; }
    
        public void Load ( string filePath )
        {
            var shapes = new List<Shape>();
    
            var doc = XDocument.Load(filePath);
    
            var elements = doc.Root.Descendants("Shape");
            foreach (var element in elements)
            {
                var shape = ReadShape(element);
                shapes.Add(shape);
            };
    
            Shapes = shapes;
        }
    
        public void Save ( string filePath )
        {
            var root = new XElement("Shapes");
            var doc = new XDocument(root);
    
            foreach (var shape in Shapes)
            {
                root.Add(WriteShape(shape));
            };
    
            doc.Save(filePath);
        }
    
        private Shape ReadShape ( XElement element )
        {
            //Parse XML
            return new Shape();
        }
    
        private XElement WriteShape ( Shape shape )
        {
            //TODO: Set up XML
            return new XElement("Shape");
        }
    }

    Here's updated code for writing.

    private XElement WriteShape ( Shape shape )
    {
        var panels = new XElement("Panels");
                
        foreach (var panel in shape.Panels)
            panels.Add(WritePanel(panel));
    
        return new XElement("Shape",
                            new XAttribute("Name", shape.Name),
                            panels);
    }
    
    private XElement WritePanel ( Panel panel )
    {
        var sides = new XElement("Sides");
    
        foreach (var side in panel.Sides)
            sides.Add(WriteSide(side));
    
        return new XElement("Panel", sides);            
    }
    
    private XElement WriteSide ( Side side )
    {
        var positions = new XElement("Positions");
    
        foreach (var position in side.Positions)
            positions.Add(new XElement("Position",
                            new XAttribute("X", position.X),
                            new XAttribute("Y", position.Y)));
    
        return new XElement("Side", positions);
    }



    Michael Taylor http://www.michaeltaylorp3.net


    Tuesday, December 18, 2018 3:02 PM
    Moderator

All replies

  • What does your app need to do with the XML? That will determine the best course of action. If you need to find specific items and make simple changes then XDocument may be quickest. But if you need to make arbitrary changes and/or generate a completely different XML file then business objects would probably be cleaner.

    Michael Taylor http://www.michaeltaylorp3.net

    Monday, December 17, 2018 8:31 PM
    Moderator
  • Hello Michael,

     

    for the current project, it is sufficient.

     

    But in the spring there will be a bigger project with different XML structures.

    If you could show me what's possible here.

    A short overview. With detail questions, I'm sure back.

     

    Greetings Markus

    Tuesday, December 18, 2018 6:36 AM
  • It will ultimately depend upon what you're doing. For simple changes XDocument is probably the easiest. I provided an example of how to do that in your other post. You can rather easily add and query XML using it. 

    If all the XML structures are different but return effectively the same data then I'd switch to business objects to work with and use separate "Document" classes to handle serializing/deserializing XML. Depending upon the format you can use the built in XmlSerializer to handle this automatically. But the builtin serializer requires certain rules be followed. If you don't have control over the XML then it will be harder to use. In that case you'll need to serialize by hand. Again though you could use business objects for your manipulation and then use XDocument to read/write. Here's a very simple example (note that the XmlSerializer can do this structure as well) if you wanted to go that route.

    class Program
    {
        static void Main ( string[] args )
        {
            var shapes = new[]
            {
                new Shape() {
                    Name = "S1",
                    Panels = new []
                    {
                        new Panel()
                        {
                            Sides = new []
                            {
                                new Side()
                                {
                                    Positions = new []
                                    {
                                        new Position() { X = 10, Y = 10 },
                                        new Position() { X = 20, Y = 20 }
                                    }
                                },
                                new Side()
                                {
                                    Positions = new[]
                                    {
                                        new Position() { X = 30, Y = 30 }
                                    }
                                }
                            }
                        }
                    }
                }
            };
    
            //Save to XML
            var doc = new ShapeDocument();
            doc.Shapes = shapes;
            doc.Save("shapes.xml");
    
            //Read it back
            doc = new ShapeDocument();
            doc.Load("shapes.xml");
    
            var newShapes = doc.Shapes;
        }
    }
    
    public class Shape
    {
        public string Name { get; set; }
    
        public IEnumerable<Panel> Panels { get; set; }
    }
    
    public class Panel
    {
        public IEnumerable<Side> Sides { get; set; }
    }
    
    public class Side
    {
        public IEnumerable<Position> Positions { get; set; }
    }
    
    public class Position
    {
        public double X { get; set; }
        public double Y { get; set; }
    }
    
    public class ShapeDocument
    {
        public IEnumerable<Shape> Shapes { get; set; }
    
        public void Load ( string filePath )
        {
            var shapes = new List<Shape>();
    
            var doc = XDocument.Load(filePath);
    
            var elements = doc.Root.Descendants("Shape");
            foreach (var element in elements)
            {
                var shape = ReadShape(element);
                shapes.Add(shape);
            };
    
            Shapes = shapes;
        }
    
        public void Save ( string filePath )
        {
            var root = new XElement("Shapes");
            var doc = new XDocument(root);
    
            foreach (var shape in Shapes)
            {
                root.Add(WriteShape(shape));
            };
    
            doc.Save(filePath);
        }
    
        private Shape ReadShape ( XElement element )
        {
            //Parse XML
            return new Shape();
        }
    
        private XElement WriteShape ( Shape shape )
        {
            //TODO: Set up XML
            return new XElement("Shape");
        }
    }

    Here's updated code for writing.

    private XElement WriteShape ( Shape shape )
    {
        var panels = new XElement("Panels");
                
        foreach (var panel in shape.Panels)
            panels.Add(WritePanel(panel));
    
        return new XElement("Shape",
                            new XAttribute("Name", shape.Name),
                            panels);
    }
    
    private XElement WritePanel ( Panel panel )
    {
        var sides = new XElement("Sides");
    
        foreach (var side in panel.Sides)
            sides.Add(WriteSide(side));
    
        return new XElement("Panel", sides);            
    }
    
    private XElement WriteSide ( Side side )
    {
        var positions = new XElement("Positions");
    
        foreach (var position in side.Positions)
            positions.Add(new XElement("Position",
                            new XAttribute("X", position.X),
                            new XAttribute("Y", position.Y)));
    
        return new XElement("Side", positions);
    }



    Michael Taylor http://www.michaeltaylorp3.net


    Tuesday, December 18, 2018 3:02 PM
    Moderator
  • Hello Michael,

    thanks for the rersponse.

    With best regards Markus

    Wednesday, December 19, 2018 5:19 PM