XML序列化-根节点的动态命名空间

问题描述 投票:0回答:1

这是我的课:

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

我使用这个类来创建多个 xml 文件。我的问题是 xml 之一需要与其他完全不同的根命名空间。

例如,大多数 xml 文件都使用此命名空间:

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

但是一个 xml 文件使用不同的命名空间(+ 2 个以上):

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

我尝试了各种方法来在运行时创建动态命名空间,但没有任何帮助。

例如,仅关注这里的答案我创建了这样的序列化代码(但根本没有将命名空间添加到根节点!):

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

我还能尝试什么?

c# xml xml-serialization
1个回答
0
投票

我想通了。

所以,就我而言,我需要的是:

  • 在所有 xml 文件(除了一个)中,根节点只有一个名称空间,没有前缀;

  • 在一个 xml 文件中,根节点有 3 个命名空间(1 个无前缀 + 2 个默认命名空间 -“xsi”和“xsd”);

为了做到这一点,您需要使用 XmlSerializer 构造函数,您可以在其中为 xml 文件设置默认命名空间,而无需前缀。

但是仅仅改变这一点,我最终在所有 xml 文件中获得了额外的 2 个默认命名空间(“xsi”和“xsd”),但我需要在大多数 xml 文件(除了一个)中排除它。

所以我的解决方案是这样的:

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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.