首页 > 解决方案 > 在 xml 序列化时连接第三方元素

问题描述

我必须以下列方式序列化 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#xmlxml-serialization

解决方案


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

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

推荐阅读