0

This is my class:

 [XmlRoot(ElementName = "Package")]
 public class Package<T>: MyBase
 {
     public Messages<T> Messages
     {
       get { return _messages; }
       set { _messages = value; OnPropertyChanged(); }
     }
     private Messages<T> _messages;
 }

I'm using this Class for creating multiple xml files. My problem is that one of xml's needs completely different Root namespace than others.

For example, most of xml file uses this namespace:

<Package xmlns="http://www.fsi.de/Schemas/2019/02/PZDIP">
  <Messages Id="OS202417483061">
    <ID>EDS2</ID>   
    <Date>2024-04-17</Date>
    <Time>08:48:30</Time> 

      ...... //body of xml

  </Messages>
</Package>

but one xml file uses different namespace (+ 2 more):

<Package xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.fsi.de/Schemas/2015/32/AAAA">
  <Messages Id="202417483061">
    <ID>FDGT</ID>   
    <Date>2024-04-17</Date>
    <Time>08:48:30</Time>  

     ...... //body of xml

  </Messages>
</Package>

I have tried various things to create dynamic namespace on runtime, but nothing has helped me.

For example, focusing just on this answer here I created code for serializing like this (but no namespaces added to root node at all!):

private string Serialize_to_xml(Package<T> _package, string _xml_type)
{
   if (_package == null)
   {
      return null;
   }
   try
   {
      var _namespaces = new XmlSerializerNamespaces();

      switch (_xml_type)
      {
         case "AD":
         case "FD":
         case "GD":
              
         _namespaces.Add("", "http://www.fsi.de/Schemas/2019/02/PZDIP");
 
         break;

         case "LD":
               
         _namespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
         _namespaces.Add("xsd", "http://www.w3.org/2001/XMLSchema");
         _namespaces.Add("", "http://www.fsi.de/Schemas/2015/32/AAAA");

         break;
      }
        
         var serializer = new XmlSerializer(_package.GetType());

         var ms = new MemoryStream();

         var settings = new XmlWriterSettings
         {
            Encoding = Encoding.GetEncoding("ISO-8859-2"),
            Indent = true
         };

         using (var writer = XmlWriter.Create(ms, settings))
         {
            serializer.Serialize(writer, _package, _namespaces);

            return Encoding.GetEncoding("ISO-8859-2").GetString(ms.ToArray());
         }
    }
    catch (Exception ex)
    {
       MessageBox.Show(ex.Message,"Error");

       return null;
    }
}

What else can I try?

8
  • Did you try with no namespaces? There are no prefixes on the tags so the default namespace is used. So both types of xml files should work using the default namespace. If it doesn't work than the issue is with the inherited base class. For an inherited class to work the xml file needs a type attribute. And the c# code needs to add XmlInclude. Commented Apr 18, 2024 at 12:25
  • @jdweng, I tried this code without explicity setting default namespace attribute on root node of Package class. But If I set default namespace, then this code serialises with namespace. Although then another problems occurs - I can't get rid of that default namespace when I try to change It - for use of second xml file, which uses different default namespace. It is added automatically. Commented Apr 18, 2024 at 12:44
  • @jdweng, I think inherited base class isn't issue, serialising xml's works fine (had to include some XmlIgnore tags for base class properties though). I have problem only with root node and It's namespaces. Commented Apr 18, 2024 at 12:51
  • What about removing the _namespaces.Add() as well. And in here : serializer.Serialize(writer, _package, _namespaces); Commented Apr 18, 2024 at 13:13
  • 1
    new XmlSerializer(_package.GetType(), "your_namespace"); - just specify desired namespace in the constructor. Commented Apr 18, 2024 at 13:31

1 Answer 1

0

I figured It out.

So, in my case what I needed was:

  • in all xml files (except one) to have root node only one namespace without prefix;

  • in one xml file have 3 namespaces in root node (1 without prefix + 2 default ones - "xsi" and "xsd");

In order to do this you need to use XmlSerializer constructor, where you can set default namespace without prefix for your xml file.

But changing just this I ended up with additional 2 default namespaces ("xsi" and "xsd") in all xml files, but I need to exclude that in most of xml files (except one).

So solution for me was this:

private string Serialize_to_xml(Package<T> _package, string _xml_type)
{
   if (_package == null)
   {
      return null;
   }
   try
   {
      var _namespaces = new XmlSerializerNamespaces();
      var _default_namespace = string.Empty;

      switch (_xml_type)
      {
         case "AD":
         case "FD":
         case "GD":
            
         _default_namespace ="http://www.fsi.de/Schemas/2019/02/PZDIP";  
         _namespaces.Add("", "http://www.fsi.de/Schemas/2019/02/PZDIP");
 
         break;

         case "LD":
           
         _default_namespace = "http://www.fsi.de/Schemas/2015/32/AAAA"; 
         _namespaces.Add("", "http://www.fsi.de/Schemas/2015/32/AAAA");
         _namespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
         _namespaces.Add("xsd", "http://www.w3.org/2001/XMLSchema");
      
         break;
      }
        
         var serializer = new XmlSerializer(_package.GetType(), _default_namespace);

         var ms = new MemoryStream();

         var settings = new XmlWriterSettings
         {
            Encoding = Encoding.GetEncoding("ISO-8859-2"),
            Indent = true
         };

         using (var writer = XmlWriter.Create(ms, settings))
         {
            serializer.Serialize(writer, _package, _namespaces);

            return Encoding.GetEncoding("ISO-8859-2").GetString(ms.ToArray());
         }
    }
    catch (Exception ex)
    {
       MessageBox.Show(ex.Message,"Error");

       return null;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.