Home > Software design >  How to change schemas in an XML document with c#
How to change schemas in an XML document with c#

Time:02-23

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;
        }

    }
}

CodePudding user response:

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);
  • Related