【问题标题】:Concatenate third party element while xml serialization在 xml 序列化时连接第三方元素
【发布时间】:2021-11-03 07:44:53
【问题描述】:

我必须按以下方式序列化 XML 结构:

<Toy>
  <Parameters>
     <!-- to be filled up by a 3rd-party function that delivers in string format -->
     <!-- the string format contains all the relevant XML tags --> 
     <!-- has the following format -->
     <!-- <Parameter> ........ </Parameter> <Parameter> ........ </Parameter> --> 
     <!-- is basically may be an element or array of elements from 3rd party with Parameter tag -->
  </Parameters>
    .
    .
    .
    .
</Toy>

我正在关注参考 - https://docs.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlserializer?view=netframework-4.6.1

此第 3 方 XML 内容也是动态的,它可能包含 Array/Scalar/Boolean 值,但确定此第 3 方内容将驻留在“Node”元素内,并且“Node”元素内的所有元素可能包含几个或没有“参数”元素

如何将此第 3 方内容附加到现有的 XML 序列化过程中?

我尝试通过@Charles 的提示通过以下方式实现它:

using System;
using System.Xml;
using System.Xml.Serialization;
using System.Collections.Generic;

public class Program
{
  public class Toy
  {
    [XmlArray(IsNullable = true)]
    public XmlElement[] Parameters { get; set; }

    public string Bar { get; set; }
  }
  
  public static void Main(string[] args)
  {

    var xmlStringList = new List<string>();

    xmlStringList.Add("<Parameter><Scalar>5</Scalar></Parameter>");
    xmlStringList.Add("<Parameter><Scalar>50</Scalar></Parameter>");
    xmlStringList.Add("<Parameter><Scalar><Alu>67</Alu></Scalar></Parameter>");

    var doc = new XmlDocument();

    var elementList = new List<XmlElement>();

    foreach (var xmlItem in xmlStringList)
    {
        doc.LoadXml(xmlItem);
        elementList.Add(doc.DocumentElement);
    }

    var toy = new Toy
    {
        Parameters = elementList.ToArray(),
        Bar = "2"
    };

    var serializer = new XmlSerializer(typeof(Toy));
    serializer.Serialize(Console.Out,toy);
  }
}

但结果并不如预期

<?xml version="1.0" encoding="Codepage - 850"?>
<Toy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Parameters>
    <XmlElement>
      <Parameter>
        <Scalar>5</Scalar>
      </Parameter>
    </XmlElement>
    <XmlElement>
      <Parameter>
        <Scalar>50</Scalar>
      </Parameter>
    </XmlElement>
    <XmlElement>
      <Parameter>
        <Scalar>
          <Alu>67</Alu>
        </Scalar>
      </Parameter>
    </XmlElement>
  </Parameters>
  <Bar>2</Bar>
</Toy>

XmLElement 标记不应出现在输出中。无论如何要删除它?预期的输出是:

<?xml version="1.0" encoding="Codepage - 850"?>
<Toy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Parameters>    
      <Parameter>
        <Scalar>5</Scalar>
      </Parameter>        
      <Parameter>
        <Scalar>50</Scalar>
      </Parameter>        
      <Parameter>
        <Scalar>
          <Alu>67</Alu>
        </Scalar>
      </Parameter>    
  </Parameters>
  <Bar>2</Bar>
</Toy>

【问题讨论】:

    标签: c# xml xml-serialization


    【解决方案1】:

    您可以添加XmlElement 类型的属性并将您的XML 字符串加载到该DOM 中。这将被正确序列化。

    所以你可以像这样加载你的 XML:

    var doc = new XmlDocument();
    doc.LoadXml(xmlString);
    var node = doc.DocumentElement;
    

    然后为你的模型添加一个属性:

    public class Toy
    {
        public XmlElement Node { get; set; }
        public string Bar { get; set; }
    }
    

    请参阅this fiddle 以获得工作演示。

    【讨论】:

    • 如果第 3 方字符串包含以下内容,则获取异常: const string xmlString = @"110";
    • 这不是一个有效的 XML 元素,它是多个元素。如果,如您所说,所有内容都应该包含在 Node 中,那么这里最简单的做法就是将该字符串包装起来:&lt;Node&gt;&lt;Foo&gt;1&lt;/Foo&gt;&lt;Foo&gt;10&lt;/Foo&gt;&lt;/Node&gt;
    【解决方案2】:

    最终我得到了以下解决方法,仍在寻找更好的解决方案:

    using System.Xml;
    using System.Xml.Serialization;
    using System.Collections.Generic;
    using System.IO;
    
    public class Program
    {
      public class Toy
      {
        public string Bar { get; set; }
      }
    public static void Main(string[] args)
    {
        var toy = new Toy
        {
            Bar = "2"
        };
    
        var streamWriter = File.CreateText("toy.xml");
    
        var serializer = new XmlSerializer(typeof(Toy));
        serializer.Serialize(streamWriter, toy);
    
        streamWriter.Close();
    
        var xmlStringList = new List<string>();
    
        xmlStringList.Add("<Parameters>");
        xmlStringList.Add("<Parameter><Scalar>5</Scalar></Parameter>");
        xmlStringList.Add("<Parameter><Scalar>50</Scalar></Parameter>");
        xmlStringList.Add("<Parameter><Scalar><Alu>67</Alu></Scalar></Parameter>");
        xmlStringList.Add("</Parameters>");
    
        
    
        var concatXml = string.Concat(xmlStringList.ToArray());
    
    
        var doc = new XmlDocument();
        doc.Load("toy.xml");
    
        var xmlDocFragment = doc.CreateDocumentFragment();
        xmlDocFragment.InnerXml = concatXml;
    
        doc.SelectSingleNode("Toy").AppendChild(xmlDocFragment);
    
        doc.Save("toy.xml");        
        
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-09-22
      • 1970-01-01
      • 1970-01-01
      • 2011-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-21
      相关资源
      最近更新 更多