Serializing XML With Same Element Name - c#

I have been having some trouble serializing the following XML...
<Activity mc:Ignorable="sap sap2010 sads" x:Class="Main"
xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sco="clr-namespace:System.Collections.ObjectModel;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextExpression.NamespacesForImplementation>
<sco:Collection x:TypeArguments="x:String">
<x:String>System.Activities</x:String>
<x:String>System.Activities.Statements</x:String>
<x:String>System.Activities.Expressions</x:String>
</sco:Collection>
</TextExpression.NamespacesForImplementation>
<TextExpression.ReferencesForImplementation>
<sco:Collection x:TypeArguments="AssemblyReference">
<AssemblyReference>System.Activities</AssemblyReference>
<AssemblyReference>Microsoft.VisualBasic</AssemblyReference>
<AssemblyReference>mscorlib</AssemblyReference>
</sco:Collection>
</TextExpression.ReferencesForImplementation>
</Activity>
I have created the following classes to serialize the first <TextExpression.NamespacesForImplementation> element and created similar classes to serialize the <TextExpression.ReferencesForImplementation> which work individually...
[XmlRoot(Namespace = "http://schemas.microsoft.com/netfx/2009/xaml/activities")]
public class Activity
{
[XmlAttribute(AttributeName = "Ignorable", Namespace = "http://schemas.openxmlformats.org/markup-compatibility/2006")]
public string Ignorable { get; set; }
[XmlAttribute(AttributeName = "Class", Namespace = "http://schemas.microsoft.com/winfx/2006/xaml")]
public string Class { get; set; }
[XmlNamespaceDeclarations]
public XmlSerializerNamespaces Xmlns { get; set; }
[XmlElement(ElementName = "TextExpression.NamespacesForImplementation", Namespace = "http://schemas.microsoft.com/netfx/2009/xaml/activities")]
public NamespacesForImplementation NamespacesForImplementation { get; set; }
[XmlElement(ElementName = "TextExpression.ReferencesForImplementation", Namespace = "http://schemas.microsoft.com/netfx/2009/xaml/activities")]
public ReferencesForImplementation ReferencesForImplementation { get; set; }
}
public class NamespacesForImplementation
{
[XmlElement(ElementName = "Collection", Namespace = "clr-namespace:System.Collections.ObjectModel;assembly=mscorlib")]
public StringCollection Collection { get; set; }
}
public class ReferencesForImplementation
{
[XmlElement(ElementName = "Collection", Namespace = "clr-namespace:System.Collections.ObjectModel;assembly=mscorlib")]
public ReferencesCollection Collection { get; set; }
}
public class StringCollection
{
[XmlAttribute(AttributeName = "TypeArguments", Namespace = "http://schemas.microsoft.com/winfx/2006/xaml")]
public string TypeArguments { get; set; }
[XmlElement(ElementName = "String", Namespace = "http://schemas.microsoft.com/winfx/2006/xaml")]
public List<string> String { get; set; }
}
public class ReferencesCollection
{
[XmlAttribute(AttributeName = "TypeArguments", Namespace = "http://schemas.microsoft.com/winfx/2006/xaml")]
public string TypeArguments { get; set; }
[XmlElement(ElementName = "AssemblyReference", Namespace = "http://schemas.microsoft.com/winfx/2006/xaml")]
public List<string> AssemblyReference { get; set; }
}
The above XML is valid with appropriate namespaces. The issue arises when attempting to serialize both Collection elements, since they both have different inner elements but have the same element name. Any suggestions? I should also mention I have tried using the special paste option 'XML to C#' in Visual Studio 2017, but the result captured does not provide the input result once serialized and deserialized immediately after.

You do not need for each property in a class a value when serializing. See code below :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
Activity activity = new Activity() {
Ignorable = "sap sap2010 sads",
Class = "Main",
NamespacesForImplementation = new NamespacesForImplementation() {
Collection = new StringCollection() {
TypeArguments = "x:String",
String = new List<string>() {
"System.Activities", "System.Activities.Statements", "System.Activities.Expressions"
}
}
},
ReferencesForImplementation = new ReferencesForImplementation() {
Collection = new StringCollection() {
TypeArguments = "AssemblyReference",
AssemblyReference = new List<string>() {
"System.Activities", "Microsoft.VisualBasic", "mscorlib"
}
}
}
};
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create(FILENAME, settings);
XmlSerializer serializer = new XmlSerializer(typeof(Activity));
serializer.Serialize(writer, activity);
}
}
[XmlRoot(Namespace = "http://schemas.microsoft.com/netfx/2009/xaml/activities")]
public class Activity
{
[XmlAttribute(AttributeName = "Ignorable", Namespace = "http://schemas.openxmlformats.org/markup-compatibility/2006")]
public string Ignorable { get; set; }
[XmlAttribute(AttributeName = "Class", Namespace = "http://schemas.microsoft.com/winfx/2006/xaml")]
public string Class { get; set; }
[XmlNamespaceDeclarations]
public XmlSerializerNamespaces Xmlns { get; set; }
[XmlElement(ElementName = "TextExpression.NamespacesForImplementation", Namespace = "http://schemas.microsoft.com/netfx/2009/xaml/activities")]
public NamespacesForImplementation NamespacesForImplementation { get; set; }
[XmlElement(ElementName = "TextExpression.ReferencesForImplementation", Namespace = "http://schemas.microsoft.com/netfx/2009/xaml/activities")]
public ReferencesForImplementation ReferencesForImplementation { get; set; }
}
public class NamespacesForImplementation
{
[XmlElement(ElementName = "Collection", Namespace = "clr-namespace:System.Collections.ObjectModel;assembly=mscorlib")]
public StringCollection Collection { get; set; }
}
public class ReferencesForImplementation
{
[XmlElement(ElementName = "Collection", Namespace = "clr-namespace:System.Collections.ObjectModel;assembly=mscorlib")]
public StringCollection Collection { get; set; }
}
public class StringCollection
{
[XmlAttribute(AttributeName = "TypeArguments", Namespace = "http://schemas.microsoft.com/winfx/2006/xaml")]
public string TypeArguments { get; set; }
[XmlElement(ElementName = "String", Namespace = "http://schemas.microsoft.com/winfx/2006/xaml")]
public List<string> String { get; set; }
[XmlElement(ElementName = "AssemblyReference", Namespace = "http://schemas.microsoft.com/winfx/2006/xaml")]
public List<string> AssemblyReference { get; set; }
}
}

Related

How to change schemas in an XML document with c#

I have an XML-file that looks like this:
<?xml version="1.0"?>
<paxml xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<header>
<format>LÖNIN</format>
<version>2</version>
</header>
<tidtransaktioner>
<tidtrans anstid="1418">
<tidkod>SJK</tidkod>
<datum>2022-02-02T15:20:00</datum>
<timmar>0</timmar>
</tidtrans>
<tidtrans anstid="1418">
<tidkod>SJK</tidkod>
<datum>2022-02-21T10:40:00</datum>
<timmar>0</timmar>
</tidtrans>
</tidtransaktioner>
</paxml>
I need to change the second line:
<paxml xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
To be like this:
<paxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.paxml.se/2.0/paxml.xsd">
Does anyone have any idea how this can be done?
Here is my class for the XML:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
namespace Logic.Shared.Models
{
// using System.Xml.Serialization;
// XmlSerializer serializer = new XmlSerializer(typeof(Paxml));
[XmlRoot(ElementName = "header", Namespace = "")]
public class Header
{
[XmlElement(ElementName = "format", Namespace = "")]
public string Format { get; set; }
[XmlElement(ElementName = "version", Namespace = "")]
public double Version { get; set; }
}
[XmlRoot(ElementName = "dimension", Namespace = "")]
public class Dimension
{
[XmlAttribute(AttributeName = "dim", Namespace = "")]
public int Dim { get; set; }
[XmlAttribute(AttributeName = "namn", Namespace = "")]
public string Namn { get; set; }
}
[XmlRoot(ElementName = "dimensioner", Namespace = "")]
public class Dimensioner
{
[XmlElement(ElementName = "dimension", Namespace = "")]
public List<Dimension> Dimension { get; set; }
}
[XmlRoot(ElementName = "resultatenhet", Namespace = "")]
public class Resultatenhet
{
[XmlAttribute(AttributeName = "dim", Namespace = "")]
public int Dim { get; set; }
[XmlAttribute(AttributeName = "id", Namespace = "")]
public int Id { get; set; }
[XmlAttribute(AttributeName = "namn", Namespace = "")]
public int Namn { get; set; }
}
[XmlRoot(ElementName = "resultatenheter", Namespace = "")]
public class Resultatenheter
{
[XmlElement(ElementName = "resultatenhet", Namespace = "")]
public List<Resultatenhet> Resultatenhet { get; set; }
}
[XmlRoot(ElementName = "tidtrans", Namespace = "")]
public class Tidtrans
{
[XmlElement(ElementName = "tidkod", Namespace = "")]
public string Tidkod { get; set; }
[XmlElement(ElementName = "datum", Namespace = "")]
public DateTime Datum { get; set; }
[XmlElement(ElementName = "timmar", Namespace = "")]
public double Timmar { get; set; }
[XmlAttribute(AttributeName = "anstid", Namespace = "")]
public int Anstid { get; set; }
[XmlText]
public string Text { get; set; }
[XmlElement(ElementName = "resenheter", Namespace = "")]
public Resenheter Resenheter { get; set; }
}
[XmlRoot(ElementName = "resenhet", Namespace = "")]
public class Resenhet
{
[XmlAttribute(AttributeName = "dim", Namespace = "")]
public int Dim { get; set; }
[XmlAttribute(AttributeName = "id", Namespace = "")]
public int Id { get; set; }
}
[XmlRoot(ElementName = "resenheter", Namespace = "")]
public class Resenheter
{
[XmlElement(ElementName = "resenhet", Namespace = "")]
public List<Resenhet> Resenhet { get; set; }
}
[XmlRoot(ElementName = "tidtransaktioner", Namespace = "")]
public class Tidtransaktioner
{
[XmlElement(ElementName = "tidtrans", Namespace = "")]
public List<Tidtrans> Tidtrans { get; set; }
}
[XmlRoot(ElementName = "dag", Namespace = "")]
public class Dag
{
[XmlAttribute(AttributeName = "datum", Namespace = "")]
public DateTime Datum { get; set; }
[XmlAttribute(AttributeName = "timmar", Namespace = "")]
public double Timmar { get; set; }
}
[XmlRoot(ElementName = "schema", Namespace = "")]
public class Schema
{
[XmlElement(ElementName = "dag", Namespace = "")]
public List<Dag> Dag { get; set; }
[XmlAttribute(AttributeName = "anstid", Namespace = "")]
public int Anstid { get; set; }
}
[XmlRoot(ElementName = "schematransaktioner", Namespace = "")]
public class Schematransaktioner
{
[XmlElement(ElementName = "schema", Namespace = "")]
public List<Schema> Schema { get; set; }
}
[XmlRoot(ElementName = "paxml", Namespace = "")]
public class Paxml
{
[XmlElement(ElementName = "header", Namespace = "")]
public Header Header { get; set; }
[XmlElement(ElementName = "dimensioner", Namespace = "")]
public Dimensioner Dimensioner { get; set; }
[XmlElement(ElementName = "resultatenheter", Namespace = "")]
public Resultatenheter Resultatenheter { get; set; }
[XmlElement(ElementName = "tidtransaktioner", Namespace = "")]
public Tidtransaktioner Tidtransaktioner { get; set; }
[XmlElement(ElementName = "schematransaktioner", Namespace = "")]
public Schematransaktioner Schematransaktioner { get; set; }
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Xsi { get; set; }
[XmlAttribute(AttributeName = "noNamespaceSchemaLocation", Namespace = "http://www.paxml.se/2.0/paxml.xsd")]
public string NoNamespaceSchemaLocation { get; set; }
[XmlText]
public string Text { get; set; }
}
}
This class is generated by an XML-file generator. As you can see I have been trying to add XML attributes to manually change the namespaces.
And this is the class for the logic:
using Logic.Mobigo.Services;
using Logic.Shared.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
namespace Logic.Services
{
public class XMLService
{
private readonly MobigoTimeService _mobigoTimeService;
private readonly MobigoUserService _mobigoUserService;
public XMLService(MobigoTimeService mobigoTimeService, MobigoUserService mobigoUserService)
{
_mobigoTimeService = mobigoTimeService;
_mobigoUserService = mobigoUserService;
}
public async Task<bool> Xml()
{
var timeRows = await _mobigoTimeService.List();
var xml = new Paxml();
xml.Header = new Header();
xml.Header.Format = "LÖNIN";
xml.Header.Version = 2.0;
var tidTrans = new List<Tidtrans>();
foreach (var timeRow in timeRows)
{
var user = await _mobigoUserService.GetByUserSign(timeRow.UserSign);
;
tidTrans.Add(new Tidtrans
{
Anstid = 1418, //int.Parse(user.EmployeeNr),
Tidkod = "SJK", //timeRow.TimeType.TimeCode,
//hur göra med datum vid månadsöverskridelse????
Datum = timeRow.StopDate,
Timmar = timeRow.TimeAmount,
});
}
xml.Tidtransaktioner = new Tidtransaktioner
{
Tidtrans = tidTrans,
};
var writer = new XmlSerializer(typeof(Paxml));
var path = "C:\\Work\\Git\\LIM\\PDF\\" + "testfile.xml";
System.IO.FileStream file = System.IO.File.Create(path);
writer.Serialize(file, xml);
file.Close();
return true;
}
}
}
You're not too far off, but you're muddling namespaces and values. You want an attribute called noNamespaceSchemaLocation in the namespace http://www.w3.org/2001/XMLSchema-instance with the value http://www.paxml.se/2.0/paxml.xsd. That would look like this:
[XmlAttribute(AttributeName = "noNamespaceSchemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string NoNamespaceSchemaLocation { get; set; } = "http://www.paxml.se/2.0/paxml.xsd";
And the root XML produced would look like this by default:
<paxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="http://www.paxml.se/2.0/paxml.xsd" />
This is semantically the same as what you require, and shouldn't cause any issues as a result. But if you really want to get rid of the namespace declaration for xsd, you can supply an XmlSerializerNamespaces that only has the namespace you need:
var ns = new XmlSerializerNamespaces();
ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
var serializer = new XmlSerializer(typeof(Paxml));
serializer.Serialize(file, xml, ns);

Deserialize XML same items with different tag

This is an XML example I want to deserialize and use in a Desktop App, where the user could insert an XML like this one:
<Settings>
<FileName>C:\Users\myniceuser\Desktop\hello.xmldoc</FileName>
<Zones>
<Row1>
<Address>2</Address>strong text
<Zone>2</Zone>
<Installed>True</Installed>
</Row1>
<Row2>
<Address>3</Address>
<Zone>2</Zone>
<Installed>True</Installed>
</Row2>
<Row3>
<Address>4</Address>
<Zone>2</Zone>
<Installed>True</Installed>
</Row3>
<Row4>
<Address>5</Address>
<Zone>2</Zone>
<Installed>True</Installed>
</Row4>
</Zones>
<Network_IP>010.000.008.072</Network_IP>
<Ethernet_Enable>true</Ethernet_Enable>
<Language>1</Language>
</Settings>
The class I implemented is this one:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace MyApp.Models
{
[XmlRoot(ElementName = "Settings")]
public class XML_Settings
{
[XmlElement(ElementName = "FileName")]
public string FileName { get; set; }
//[XmlElement(ElementName = "Zones")]
[XmlElement(ElementName ="Zones")]
public Zones_Points[] Zones_Points { get; set; }
[XmlElement(ElementName = "Network_IP")]
public string NetworkIP { get; set; }
[XmlElement(ElementName = "Ethernet_Enable")]
public bool EthernetEnable { get; set; }
[XmlElement(ElementName = "Language")]
public int Language { get; set; }
}
[XmlRoot(ElementName = "")]
public partial class Zones_Points
{
[XmlElement(ElementName ="Address")]
public int Address { get; set; }
[XmlElement(ElementName ="Zone")]
public int PointZone { get; set; }
[XmlElement(ElementName ="Installed")]
public bool Installed { get; set; }
}
}
I deserialize like this:
Models.XML_Settings inputted_xml = new();
using StreamReader stream_xml = new StreamReader(xmlfile_path, CodePagesEncodingProvider.Instance.GetEncoding(1253));
XmlSerializer serializer = new XmlSerializer(typeof(Models.XML_Settings));
try
{
Models.XML_Settings input = (Models.XML_GR6500)serializer.Deserialize(stream_xml);
}
catch (Exception exception)
{
MessageBox.Show(exception.Message);
}
I want my app to input files in XML like this one, and convert their data to a class that i can use.
The object "input" created by the Deserialization got every data correct, except the Zones, those that in XML have the "Row" tags. Those "rows" could every time be more or less that 4.
What can I do to have the items with the row tags deserialized and inputted into a Zones_Points list or array?
Use IXmlSerializable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.Xml.Linq;
namespace ConsoleApplication2
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(XML_Settings));
XML_Settings settings = (XML_Settings)serializer.Deserialize(reader);
}
}
[XmlRoot("Settings")]
public class XML_Settings
{
[XmlElement(ElementName = "FileName")]
public string FileName { get; set; }
[XmlElement(ElementName = "Zones")]
public Zones_Points Zones_Point { get; set; }
[XmlElement(ElementName = "Network_IP")]
public string NetworkIP { get; set; }
[XmlElement(ElementName = "Ethernet_Enable")]
public bool EthernetEnable { get; set; }
[XmlElement(ElementName = "Language")]
public int Language { get; set; }
}
public partial class Zones_Points : IXmlSerializable
{
// Xml Serialization Infrastructure
[XmlElement(ElementName = "Zones")]
public List<Zones_Point> Points { get; set; }
public void WriteXml(XmlWriter writer)
{
}
public void ReadXml(XmlReader reader)
{
XElement zones = (XElement)XElement.ReadFrom(reader);
Points = new List<Zones_Point>();
foreach (XElement row in zones.Elements())
{
Zones_Point Point = new Zones_Point();
Points.Add(Point);
Point.Address = (int)row.Element("Address");
Point.PointZone = (int)row.Element("Zone");
Point.Installed = (Boolean)row.Element("Installed");
}
}
public XmlSchema GetSchema()
{
return (null);
}
}
public partial class Zones_Point
{
[XmlElement(ElementName = "Address")]
public int Address { get; set; }
[XmlElement(ElementName = "Zone")]
public int PointZone { get; set; }
[XmlElement(ElementName = "Installed")]
public bool Installed { get; set; }
}
}

How do I Deserialize this XML document in C#

This is my XML:
<?xml version="1.0" encoding="utf-8"?>
<Fruit>
<Fruit_group name='Tropical'>
<fruit_types name ='Tropical Used'>
<fruit>bananas</fruit>
<fruit>mangoes</fruit>
</fruit_types>
</Fruit_group>
<Fruit_group name='Citrus'>
<fruit_types name ='Citruses Used'>
<fruit>orange</fruit>
<fruit>lime</fruit>
<fruit>grapefruit</fruit>
<excluded_fruits>
<fruit>mandarin</fruit>
</excluded_fruits>
</fruit_types>
</Fruit_group>
</Fruit>
And this is a sample of my XML text..
Is there a way to deserialize it and keep the name of the elements too..
I mean I would like to have like:
Tropical -> Tropical Used -> fruit -> bananas, mangoes
Citrus->Citruses Used ->
fruit = orange, lime, grapefruit
excluded = mandarin....
Something like this...
Could someone help me to understand how does this work?
You can use XML to c# website to create a class according to XML.
In this case, I've got this example
using System;
using System.Xml.Serialization;
using System.Collections.Generic;
namespace Xml2CSharp
{
[XmlRoot(ElementName="fruit_types")]
public class Fruit_types {
[XmlElement(ElementName="fruit")]
public List<string> Fruit { get; set; }
[XmlAttribute(AttributeName="name")]
public string Name { get; set; }
[XmlElement(ElementName="excluded_fruits")]
public Excluded_fruits Excluded_fruits { get; set; }
}
[XmlRoot(ElementName="Fruit_group")]
public class Fruit_group {
[XmlElement(ElementName="fruit_types")]
public Fruit_types Fruit_types { get; set; }
[XmlAttribute(AttributeName="name")]
public string Name { get; set; }
}
[XmlRoot(ElementName="excluded_fruits")]
public class Excluded_fruits {
[XmlElement(ElementName="fruit")]
public string Fruit { get; set; }
}
[XmlRoot(ElementName="Fruit")]
public class Fruit {
[XmlElement(ElementName="Fruit_group")]
public List<Fruit_group> Fruit_group { get; set; }
}
}
Also, You could read this article about XML deserialization.
I suggest using xmltocsharp to convert the XML to Model and do required alterations. For example change the string to List<string> under Excluded_fruits
[XmlRoot(ElementName = "fruit_types")]
public class Fruit_types
{
[XmlElement(ElementName = "fruit")]
public List<string> Fruit { get; set; }
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
[XmlElement(ElementName = "excluded_fruits")]
public Excluded_fruits Excluded_fruits { get; set; }
}
[XmlRoot(ElementName = "Fruit_group")]
public class Fruit_group
{
[XmlElement(ElementName = "fruit_types")]
public Fruit_types Fruit_types { get; set; }
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
}
[XmlRoot(ElementName = "excluded_fruits")]
public class Excluded_fruits
{
[XmlElement(ElementName = "fruit")]
public List<string> Fruit { get; set; }
}
[XmlRoot(ElementName = "Fruit")]
public class Fruit
{
[XmlElement(ElementName = "Fruit_group")]
public List<Fruit_group> Fruit_group { get; set; }
}
Once the model is ready, you can use XmlSerializer to Deserialize the xml file
using (StreamReader r = new StreamReader(xmlfilepath))
{
string xmlString = r.ReadToEnd();
XmlSerializer ser = new XmlSerializer(typeof(Fruit));
using (TextReader reader = new StringReader(xmlString))
{
var fruits = (Fruit)ser.Deserialize(reader);
foreach(var fruitgroup in fruits.Fruit_group)
{
Console.Write($"{fruitgroup.Name} -> ");
Console.Write($"{fruitgroup.Fruit_types.Name} -> ");
Console.Write($"fruit = {string.Join(",", fruitgroup.Fruit_types.Fruit.ToArray())}; ");
if (fruitgroup.Fruit_types.Excluded_fruits?.Fruit?.Count() > 0)
Console.Write($"excluded = {string.Join(",", fruitgroup.Fruit_types.Excluded_fruits.Fruit.ToArray())}{Environment.NewLine}");
else
Console.WriteLine();
}
}
}
I like getting flatter results doing a custom parsing using xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
List<Fruit_Group> groups = doc.Descendants("Fruit_group").Select(x => new Fruit_Group()
{
groupName = (string)x.Attribute("name"),
typeName = (string)x.Element("fruit_types").Attribute("name"),
fruits = x.Elements("fruit_types").Elements("fruit").Select(y => (string)y).ToArray(),
excluded = x.Descendants("excluded_fruits").Elements("fruit").Select(y => (string)y).ToArray()
}).ToList();
}
}
public class Fruit_Group
{
public string groupName { get; set;}
public string typeName { get; set; }
public string[] fruits { get; set; }
public string[] excluded { get; set; }
}
}

Batch Data Extraction Script

apologies for the newbie question as I am very new to the world of programming etc.
I have a large XML file containing (see link below). It contains an ID number for legal entities (LEI) followed by the ID for their respective parent company.
Example from the XML file
The yellow is the entity LEI number and the green is the parent company LEI.
I would like to create some sort of batch script or GUI so I can enter a list of entity (green) LEI numbers and then given an output of all the corresponding parent LEI numbers.
Here is the file for anyone wondering: https://leidata.gleif.org/api/v1/concatenated-files/rr/20171025/zip
I am very inexperienced so I am not sure where to start.
Many thanks
Copy the entire file content to clipboard, then open your visual studio project and go to menu -> edit -> paste special -> paste as xml classes. This will generate a bunch of classes in the file you have currently open. Save this file. Then you use this code to load the file and return the loaded data:
public static RelationshipData LoadFile(string fileName)
{
var serializer = new XmlSerializer(typeof(Items));
RelationshipData data;
using (Stream r = new FileStream(filename, FileMode.Open))
{
data = (RelationshipData)serializer.Deserialize(r);
}
return data;
}
Now you should be able to access the file content using the properties of the returned data object. Haven't used this method with xml-data that uses prefixes, but I think this will be handled too...
With this data you should build up a dictionary or something like that that suits your needs that maps one ID to the other ID.
You should really start reading why and how this works...
NOT TESTED
I think I got most of the elements. You need to do some careful checking since there are a lot of nodes. I added a writer so I can use Beyond Compare to check if I got all the nodes. Fixed some errors. Still need some minor tweaks.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
const string INPUT_FILENAME = #"c:\temp\test.xml";
const string OUTPUT_FILENAME = #"c:\temp\test1.xml";
static void Main(string[] args)
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.CheckCharacters = false;
XmlReader reader = XmlReader.Create(INPUT_FILENAME, settings);
XmlSerializer serializer = new XmlSerializer(typeof(RelationshipDataRelationshipData));
RelationshipDataRelationshipData relationshipDataRelationshipData = (RelationshipDataRelationshipData)serializer.Deserialize(reader);
XmlWriterSettings wSettings = new XmlWriterSettings();
wSettings.Indent = true;
XmlWriter writer = XmlWriter.Create(OUTPUT_FILENAME, wSettings);
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("rr", "http://www.gleif.org/data/schema/rr/2016");
ns.Add("gleif", "http://www.gleif.org/concatenated-file/header-extension/2.0");
serializer.Serialize(writer, relationshipDataRelationshipData, ns);
writer.Flush();
writer.Close();
}
}
[XmlRoot(ElementName = "RelationshipData", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public class RelationshipDataRelationshipData
{
[XmlElement("Header")]
public Header header { get; set; }
[XmlElement("RelationshipRecords", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public RelationshipRecords relationshipRecords { get; set; }
}
[XmlRoot(ElementName = "Header", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public class Header
{
[XmlElement("ContentDate")]
public DateTime ContentDate { get; set; }
[XmlElement("FileContent")]
public string FileContent { get; set; }
[XmlElement("RecordCount")]
public int RecordCount { get; set; }
[XmlElement("Extension", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public Extension extension { get; set; }
}
[XmlRoot(ElementName = "Extension", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public class Extension
{
[XmlElement(ElementName = "Sources", Namespace = "http://www.gleif.org/concatenated-file/header-extension/2.0")]
public Sourses sources { get; set; }
}
[XmlRoot(ElementName = "Sources", Namespace = "http://www.gleif.org/concatenated-file/header-extension/2.0")]
public class Sourses
{
[XmlElement("Source")]
public List<Source> source { get; set; }
}
[XmlRoot(ElementName = "Source", Namespace = "http://www.gleif.org/concatenated-file/header-extension/2.0")]
public class Source
{
[XmlElement("ContentDate")]
public DateTime ContentDate { get; set; }
[XmlElement("Originator")]
public string Originator { get; set; }
[XmlElement("RecordCount")]
public int RecordCount { get; set; }
}
[XmlRoot(ElementName = "RelationshipRecords", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public class RelationshipRecords
{
[XmlElement("RelationshipRecord")]
public List<RelationshipRecord> relationshipRecord { get; set; }
}
[XmlRoot(ElementName = "RelationshipRecord", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public class RelationshipRecord
{
[XmlElement("Relationship")]
public Relationship relationship { get; set; }
[XmlElement("Registration")]
public Registration registration { get; set; }
[XmlElement("Extension", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public Extension extension { get; set; }
}
[XmlRoot(ElementName = "Relationship", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public class Relationship
{
[XmlElement("StartNode")]
public Node StartNode { get; set; }
[XmlElement("EndNode")]
public Node EndNode { get; set; }
public string RelationshipType { get; set; }
[XmlElement("RelationshipPeriods")]
public RelationshipPeriods relationshipPeriods { get; set; }
public string RelationshipStatus { get; set; }
[XmlElement("RelationshipQualifiers")]
public RelationshipQualifiers relationshipQualifiers { get; set; }
}
[XmlRoot(ElementName = "Node", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public class Node
{
public string NodeID { get; set; }
public string NodeIDType { get; set; }
}
[XmlRoot(ElementName = "class RelationshipQualifiers", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public class RelationshipQualifiers
{
[XmlElement("RelationshipQualifier")]
public RelationshipQualifier relationshipQualifier { get; set; }
}
[XmlRoot(ElementName = "class RelationshipQualifier", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public class RelationshipQualifier
{
public string QualifierDimension { get; set; }
public string QualifierCategory { get; set; }
}
[XmlRoot(ElementName = "Registration", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public class Registration
{
public DateTime InitialRegistrationDate { get; set; }
public DateTime LastUpdateDate { get; set; }
public string RegistrationStatus { get; set; }
public DateTime NextRenewalDate { get; set; }
public string ManagingLOU { get; set; }
public string ValidationSources { get; set; }
public string ValidationDocuments { get; set; }
}
[XmlRoot(ElementName = "class RelationshipPeriods", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public class RelationshipPeriods
{
[XmlElement("RelationshipPeriod")]
public List<RelationshipPeriod> relationshipPeriod { get; set; }
}
[XmlRoot(ElementName = "class RelationshipPeriod", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public class RelationshipPeriod
{
[XmlElement("StartDate")]
public DateTime StartDate { get; set; }
[XmlElement("EndDate")]
public DateTime EndDate { get; set; }
[XmlElement("PeriodType")]
public string PeriodType { get; set; }
}
[XmlRoot(ElementName = "class RelationshipQuantifiers", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public class RelationshipQuantifiers
{
[XmlElement("RelationshipQuantifier")]
public List<RelationshipQuantifier> relationshipQuantifier { get; set; }
}
[XmlRoot(ElementName = "class RelationshipQuantifier", Namespace = "http://www.gleif.org/data/schema/rr/2016")]
public class RelationshipQuantifier
{
[XmlElement("MeasurementMethod")]
public DateTime MeasurementMethod { get; set; }
[XmlElement("QuantifierAmount")]
public decimal QuantifierAmount { get; set; }
[XmlElement("QuantifierUnits")]
public string QuantifierUnits { get; set; }
}
}

Error when Deserializing XML into c# class derived from xsd.exe with namespace

I will start off with I have read all of the other answers to this question and all of them (albeit good solutions) did not work in my case
I created a c# class from my xsd file with
xsd.exe /c neworder.xsd
It generated a class of 7000+ lines so I'll post relevant parts of it.
using System;
using System.Diagnostics;
using System.Xml.Serialization;
using System.Collections;
using System.Xml.Schema;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Xml;
using System.Collections.Generic;
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.34234")]
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.foo.com/schemas/w/v1.0")]
[System.Xml.Serialization.XmlRootAttribute("new-order", Namespace = "http://www.foo.com/schemas/w/v1.0")]
public partial class neworder
{
private List<customertype> customersField;
private string suppliercodeField;
private string versionField;
private static System.Xml.Serialization.XmlSerializer serializer;
public neworder()
{
this.customersField = new List<customertype>();
}
[System.Xml.Serialization.XmlArrayAttribute(Order = 0)]
[System.Xml.Serialization.XmlArrayItemAttribute("customer",IsNullable = false)]
public List<customertype> customers
{
get
{
return this.customersField;
}
set
{
this.customersField = value;
}
}
[System.Xml.Serialization.XmlAttributeAttribute("supplier-code")]
public string suppliercode
{
get
{
return this.suppliercodeField;
}
set
{
this.suppliercodeField = value;
}
}
[System.Xml.Serialization.XmlAttributeAttribute("version")]
public string version
{
get
{
return this.versionField;
}
set
{
this.versionField = value;
}
}
private static System.Xml.Serialization.XmlSerializer Serializer
{
get
{
if ((serializer == null))
{
serializer = new System.Xml.Serialization.XmlSerializer(typeof(neworder));
}
return serializer;
}
}
public static neworder Deserialize(string xml)
{
System.IO.StringReader stringReader = null;
try
{
stringReader = new System.IO.StringReader(xml);
return ((neworder)(Serializer.Deserialize(System.Xml.XmlReader.Create(stringReader))));
}
finally
{
if ((stringReader != null))
{
stringReader.Dispose();
}
}
}
That is just a small snippet, the rest isn't that important right now as I feel like if this gets solved, I can solve the rest.
This is the beginning part of the XML file
<new-order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.foo.com/schema/w/v1.0" version="1.0" supplier-code="FAKECODE" schemaLocation="http://www.foo.com/schemas/w/v1.0/TransmissionEnvelope.xsd">
<customers>
<customer w-number="123456" customer-number="12345-12345">
<client-info>
<client-name>John Doe</client-name>
<w-id>433348</w-id>
</client-info>
<transferee-name>
<first>John</first>
<last>Doe</last>
</transferee-name>
<spouse-name>
<first />
<last />
</spouse-name>
<o-address>
<street1>123 Fake st</street1>
<city>Fakeville</city>
<state>CA</state>
<postal-code>90210</postal-code>
<country>USA</country>
</o-address>
<d-address>
<street1 />
<city>harbour</city>
<state>VA</state>
<postal-code>55555</postal-code>
<country>USA</country>
</d-address>
<contact-info>
<phone>
<phone-type>CELL</phone-type>
<phone-number>555-555-5555</phone-number>
</phone>
<phone>
<phone-type>HOME</phone-type>
<phone-number>555-555-5555</phone-number>
</phone>
<phone>
<phone-type>WORK</phone-type>
<phone-number />
</phone>
<email>johndoe#email.com</email>
<comments>Just any comments here</comments>
</contact-info>
</customer>
</customers>
</new-order>
I try to deserialize it with the following
XmlSerializer ser = new XmlSerializer(typeof(neworder));
neworder feed = (neworder)ser.Deserialize(new FileStream(filePath, FileMode.Open)) ;
The error that I get is the infamous:
There is an error in XML document (1, 2).
http://www.foo.com/schema/w/v1.0'> was not expected.
I've read over and over again about making sure the root note as attribute XMLROOT which the above does. And it has the right namespace.
I've tried changing XmlRootAttribute to XmlRoot. Nothing.
I've tried removing the namespace and re-doing the class and nothing.
Wrecking my brain on what could be wrong here because everything seems legit.
Try this.... (for the XML that you have posted)
Using.....
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
Classes.....
[XmlRoot(ElementName = "client-info", Namespace = "http://www.foo.com/schema/w/v1.0")]
public class Clientinfo
{
[XmlElement(ElementName = "client-name", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string Clientname { get; set; }
[XmlElement(ElementName = "w-id", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string Wid { get; set; }
}
[XmlRoot(ElementName = "transferee-name", Namespace = "http://www.foo.com/schema/w/v1.0")]
public class Transfereename
{
[XmlElement(ElementName = "first", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string First { get; set; }
[XmlElement(ElementName = "last", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string Last { get; set; }
}
[XmlRoot(ElementName = "spouse-name", Namespace = "http://www.foo.com/schema/w/v1.0")]
public class Spousename
{
[XmlElement(ElementName = "first", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string First { get; set; }
[XmlElement(ElementName = "last", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string Last { get; set; }
}
[XmlRoot(ElementName = "o-address", Namespace = "http://www.foo.com/schema/w/v1.0")]
public class Oaddress
{
[XmlElement(ElementName = "street1", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string Street1 { get; set; }
[XmlElement(ElementName = "city", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string City { get; set; }
[XmlElement(ElementName = "state", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string State { get; set; }
[XmlElement(ElementName = "postal-code", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string Postalcode { get; set; }
[XmlElement(ElementName = "country", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string Country { get; set; }
}
[XmlRoot(ElementName = "d-address", Namespace = "http://www.foo.com/schema/w/v1.0")]
public class Daddress
{
[XmlElement(ElementName = "street1", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string Street1 { get; set; }
[XmlElement(ElementName = "city", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string City { get; set; }
[XmlElement(ElementName = "state", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string State { get; set; }
[XmlElement(ElementName = "postal-code", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string Postalcode { get; set; }
[XmlElement(ElementName = "country", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string Country { get; set; }
}
[XmlRoot(ElementName = "phone", Namespace = "http://www.foo.com/schema/w/v1.0")]
public class Phone
{
[XmlElement(ElementName = "phone-type", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string Phonetype { get; set; }
[XmlElement(ElementName = "phone-number", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string Phonenumber { get; set; }
}
[XmlRoot(ElementName = "contact-info", Namespace = "http://www.foo.com/schema/w/v1.0")]
public class Contactinfo
{
[XmlElement(ElementName = "phone", Namespace = "http://www.foo.com/schema/w/v1.0")]
public List<Phone> Phone { get; set; }
[XmlElement(ElementName = "email", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string Email { get; set; }
[XmlElement(ElementName = "comments", Namespace = "http://www.foo.com/schema/w/v1.0")]
public string Comments { get; set; }
}
[XmlRoot(ElementName = "customer", Namespace = "http://www.foo.com/schema/w/v1.0")]
public class Customer
{
[XmlElement(ElementName = "client-info", Namespace = "http://www.foo.com/schema/w/v1.0")]
public Clientinfo Clientinfo { get; set; }
[XmlElement(ElementName = "transferee-name", Namespace = "http://www.foo.com/schema/w/v1.0")]
public Transfereename Transfereename { get; set; }
[XmlElement(ElementName = "spouse-name", Namespace = "http://www.foo.com/schema/w/v1.0")]
public Spousename Spousename { get; set; }
[XmlElement(ElementName = "o-address", Namespace = "http://www.foo.com/schema/w/v1.0")]
public Oaddress Oaddress { get; set; }
[XmlElement(ElementName = "d-address", Namespace = "http://www.foo.com/schema/w/v1.0")]
public Daddress Daddress { get; set; }
[XmlElement(ElementName = "contact-info", Namespace = "http://www.foo.com/schema/w/v1.0")]
public Contactinfo Contactinfo { get; set; }
[XmlAttribute(AttributeName = "w-number")]
public string Wnumber { get; set; }
[XmlAttribute(AttributeName = "customer-number")]
public string Customernumber { get; set; }
}
[XmlRoot(ElementName = "customers", Namespace = "http://www.foo.com/schema/w/v1.0")]
public class Customers
{
[XmlElement(ElementName = "customer", Namespace = "http://www.foo.com/schema/w/v1.0")]
public Customer Customer { get; set; }
}
[XmlRoot(ElementName = "new-order", Namespace = "http://www.foo.com/schema/w/v1.0")]
public class Neworder
{
[XmlElement(ElementName = "customers", Namespace = "http://www.foo.com/schema/w/v1.0")]
public Customers Customers { get; set; }
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Xsi { get; set; }
[XmlAttribute(AttributeName = "xmlns")]
public string Xmlns { get; set; }
[XmlAttribute(AttributeName = "version")]
public string Version { get; set; }
[XmlAttribute(AttributeName = "supplier-code")]
public string Suppliercode { get; set; }
[XmlAttribute(AttributeName = "schemaLocation")]
public string SchemaLocation { get; set; }
}
Code.....
string strXML = File.ReadAllText("xml.xml");
byte[] bufXML = ASCIIEncoding.UTF8.GetBytes(strXML);
MemoryStream ms1 = new MemoryStream(bufXML);
// Deserialize to object
XmlSerializer serializer = new XmlSerializer(typeof(Neworder));
try
{
using (XmlReader reader = new XmlTextReader(ms1))
{
Neworder deserializedXML = (Neworder)serializer.Deserialize(reader);
}// put a break point here and mouse-over deserializedXML….
}
catch (Exception ex)
{
throw;
}
I am reading your XML in to a string from a file in the application build folder called xml.xml... you will need to get the XML string from somewhere else or create the xml.xml file and save your XML for the code above to work

Categories