c#从对象列表写入XML文件

时间:2017-10-30 13:51:46

标签: c# xml linq-to-xml xelement

我正面临使用XDocument写入xml文件的问题,而XElement这里的输出文件是错误的,应该如何。 这是最终的xml文件的样子,但它不符合要求。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<CMS>
  <Device Name="CM_HOST" Type="TR">
    <PortA Connected_BY="Directly">
      <Device TB="AR" ParentConnectedToPort="A" Name="Akitio" Cable="20G Passive" />
    </PortA>
    <PortA Connected_BY="Directly">
      <Device TB="AR" ParentConnectedToPort="A" Name=" doc1" Cable="20G Passive" />
    </PortA>
  </Device>
</CMS>

它应该是这样的:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<CMS>
  <Device Name="CM_HOST" Type="TR">
    <PortA Connected_BY="Directly">
      <Device TB="AR" ParentConnectedToPort="A" Name="Akitio" Cable="20G Passive" >
        <PortA>
            <Device TB="AR" ParentConnectedToPort="A" Name=" doc1" Cable="20G Passive" />
        </PortA>
      </Device>
    </PortA>
  </Device>
</CMS>

这里是我试图运行此代码的代码本身:

private void exportToXmlFile(List<Device> list)
        {
            XDocument xdoc = new XDocument(
            new XDeclaration("1.0", "utf-8", "yes"));
            XElement elm = new XElement("CMS");

            XElement hostDev = new XElement("Device");
            hostDev.Add(new XAttribute("Name", list.ElementAt(0).Name)); 
            hostDev.Add(new XAttribute("Type", list.ElementAt(0).TBType1));

            foreach (Device device in deviceToAddList)
            {
                if (device.Name != "CM_HOST")
                {
                    if(device.DeviceConnectedTo=="A")
                    {
                       if (device.ConnectedBy == "Directly")
                        {
                            XElement deviceElem = new XElement("Device");
                            XElement portAelem = new XElement("PortA");
                            portAelem.Add(new XAttribute("Connected_BY", device.ConnectedBy));
                            deviceElem.Add(new XAttribute("TB", device.TBType1));
                            deviceElem.Add(new XAttribute("ParentConnectedToPort", device.ParentConnectedTo));
                            deviceElem.Add(new XAttribute("Name", device.Name));
                            deviceElem.Add(new XAttribute("Cable", device.Cable));
                            portAelem.Add(deviceElem);
                            hostDev.Add(portAelem);

                        }

                    }
                }
            }
            elm.Add(hostDev);
            xdoc.Add(elm);
            xdoc.Save(Application.StartupPath + "\\Topology.xml");




        }

这是包含所有属性的Device类:

public class Device
    {
        string name;
        string TBType;
        string connectedBy;
        string parentConnectedTo;
        string ftdiPort;
        string cable;
        string parentName;
        string deviceConnectedTo;
        decimal plusPin;
        decimal MinusPin;
        int xmlevel;

        public Device()
        {
            this.Name = "CM_HOST";
            this.ParentName = "None";
            this.TBType1 = "TR";
            this.parentConnectedTo = "PCI";
            this.Xmlevel = 0;
            this.deviceConnectedTo = "None";
        }

        public string Name { get => name; set => name = value; }
        public string TBType1 { get => TBType; set => TBType = value; }
        public string ConnectedBy { get => connectedBy; set => connectedBy = value; }
        public string ParentConnectedTo { get => parentConnectedTo; set => parentConnectedTo = value; }
        public string FtdiPort { get => ftdiPort; set => ftdiPort = value; }
        public string Cable { get => cable; set => cable = value; }
        public string ParentName { get => parentName; set => parentName = value; }
        public string DeviceConnectedTo { get => deviceConnectedTo; set => deviceConnectedTo = value; }
        public decimal PlusPin { get => plusPin; set => plusPin = value; }
        public decimal MinusPin1 { get => MinusPin; set => MinusPin = value; }
        public int Xmlevel { get => xmlevel; set => xmlevel = value; }
    }

需要连接以下元素,不要添加为新行(: 谢谢所有人......

这就是我期望的最终输出的原因:

<?xml version="1.0" encoding="UTF-8"?>
<CMS>
  <Device TB="CM_HOST" properties="{'Name':'Host', 'Type' : 'TR' }" >
      <PortA Connected_BY= "MiniBot">
        <Device TB="TR" ParentConnectedToPort ='PortB' properties="{'Pins': {'MiniBot_minus_pin': 2, 'MiniBot_pluse_pin': 3}, 'Type': 'TR' , 'FTDI_Port':0 ,'Name':'SV_Board','Cable': '20G Passive' }" >   
          <PortB Connected_BY= "MiniBot">
            <Device TB="AR" ParentConnectedToPort ='PortB' properties="{'Pins': {'MiniBot_minus_pin': 0, 'MiniBot_pluse_pin': 1},'Type': 'AR' , 'FTDI_Port':0 ,'Name':'StarTechDoc','Cable': '20G Passive' }">
                <PortA Connected_BY= "Directly">
                    <Device TB="None" properties="{'Type': 'None' , 'FTDI_Port':0 ,'Name':'samsung-USB3','Cable': '20G Passive'}" ></Device>
                </PortA>
                <PortB Connected_BY= "ParentConnected"></PortB>
                <PortE><Device TB="None" properties="{'Type': 'None' , 'FTDI_Port':0 ,'Name':'samsung-USB3','Cable': '20G Passive'}" ></Device></PortE>
            </Device>
          </PortB>
            <PortA Connected_BY= "ParentConnected"></PortA>
          <PortE Connected_BY= "None"></PortE>
        </Device>
      </PortA>
      <PortB Connected_BY= "None"></PortB>
        </Device>
</CMS>

2 个答案:

答案 0 :(得分:0)

无需查看代码,您可以在XML文件中手动编写元素和属性。为什么不使用XML序列化?只需创建具有正确结构的类,但在类中的列表中创建元素的子元素。以这种方式构建所需的结构很容易,然后像这样序列化XML:

            XmlSerializer xmlSerializer = new XmlSerializer(typeof(*NameOfYourClass*));
            using (StringWriter writer = new StringWriter())
            {
                using (XmlTextWriter xmlWriter = new XmlTextWriter(writer))
                {
                    xmlWriter.Formatting = Formatting.Indented;
                    xmlWriter.Indentation = 4;
                    xmlSerializer.Serialize(xmlWriter, *InstanceOfYourClass*);
                    return writer.ToString());
                }
            }

为什么你的XML必须如下所示:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<CMS>
    <Device Name="CM_HOST" Type="TR">
        <PortA Connected_BY="Directly">
            <Device TB="AR" ParentConnectedToPort="A" Name="Akitio" Cable="20G Passive" >
                <PortA>
                    <Device TB="AR" ParentConnectedToPort="A" Name=" doc1" Cable="20G Passive" />
                </PortA>
            </Device>
        </PortA>
    </Device>
</CMS>

而不喜欢这个?

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<CMS>
    <Device Name="CM_HOST" Type="TR">
        <PortA Connected_BY="Directly">
            <Device TB="AR" ParentConnectedToPort="A" Name="Akitio" Cable="20G Passive" >
            <Device TB="AR" ParentConnectedToPort="A" Name=" doc1" Cable="20G Passive" />
        </PortA>
    </Device>
</CMS>

答案 1 :(得分:0)

这是我的问题的解决方案我终于得到了这个:

private void exportToXmlFile(List<Device> list)
        {
            XDocument xdoc = new XDocument(
            new XDeclaration("1.0", "utf-8", "yes"));
            XElement elm = new XElement("CMS");
            bool flag = false;
            XElement hostDev = new XElement("Device");
            hostDev.Add(new XAttribute("Name", list.ElementAt(0).Name)); 
            hostDev.Add(new XAttribute("Type", list.ElementAt(0).TBType1));
            elm.Add(hostDev);
            xdoc.Add(elm);
            foreach (Device device in deviceToAddList)
            {
                if (device.Name != "CM_HOST")
                {
                    if(device.DeviceConnectedTo=="A")
                    {
                       if (device.ConnectedBy == "Directly")
                        {
                            flag = true;
                            XElement selectedElement = xdoc.Descendants()
                            .Where(x => (string)x.Attribute("Name") == device.ParentName).FirstOrDefault();
                            XElement deviceElem = new XElement("Device");
                            XElement portAelem = new XElement("PortA");
                            portAelem.Add(new XAttribute("Connected_BY", device.ConnectedBy));
                            deviceElem.Add(new XAttribute("TB", device.TBType1));
                            deviceElem.Add(new XAttribute("ParentConnectedToPort", device.ParentConnectedTo));
                            deviceElem.Add(new XAttribute("Name", device.Name));
                            deviceElem.Add(new XAttribute("Cable", device.Cable));
                            portAelem.Add(deviceElem);
                            selectedElement.Add(portAelem);
                        }
                       if(device.ConnectedBy == "MiniBot")
                        {
                            flag = true;
                            XElement selectedElement = xdoc.Descendants()
                            .Where(x => (string)x.Attribute("Name") == device.ParentName).FirstOrDefault();
                            XElement deviceElem2 = new XElement("Device");
                            XElement portAelem2 = new XElement("PortA");
                            portAelem2.Add(new XAttribute("Connected_BY", device.ConnectedBy));
                            deviceElem2.Add(new XAttribute("TB", device.TBType1));
                            deviceElem2.Add(new XAttribute("ParentConnectedToPort", device.ParentConnectedTo));
                            deviceElem2.Add(new XAttribute("MiniBot_minus_pin", device.MinusPin1));
                            deviceElem2.Add(new XAttribute("MiniBot_pluse_pin", device.PlusPin));
                            deviceElem2.Add(new XAttribute("FTDI_Port", device.FtdiPort));
                            deviceElem2.Add(new XAttribute("Name", device.Name));
                            deviceElem2.Add(new XAttribute("Cable", device.Cable));
                            portAelem2.Add(deviceElem2);
                            selectedElement.Add(portAelem2);
                        }

                    }
                    if(device.DeviceConnectedTo=="B")
                    {
                        if (device.ConnectedBy == "Directly")
                        {
                            flag = true;
                            XElement selectedElement = xdoc.Descendants()
                            .Where(x => (string)x.Attribute("Name") == device.ParentName).FirstOrDefault();
                            XElement deviceElem = new XElement("Device");
                            XElement portBelem = new XElement("PortB");
                            portBelem.Add(new XAttribute("Connected_BY", device.ConnectedBy));
                            deviceElem.Add(new XAttribute("TB", device.TBType1));
                            deviceElem.Add(new XAttribute("ParentConnectedToPort", device.ParentConnectedTo));
                            deviceElem.Add(new XAttribute("Name", device.Name));
                            deviceElem.Add(new XAttribute("Cable", device.Cable));
                            portBelem.Add(deviceElem);
                            selectedElement.Add(portBelem);
                        }
                        if (device.ConnectedBy == "MiniBot")
                        {
                            flag = true;
                            XElement selectedElement = xdoc.Descendants()
                            .Where(x => (string)x.Attribute("Name") == device.ParentName).FirstOrDefault();
                            XElement deviceElem2 = new XElement("Device");
                            XElement portBelem2 = new XElement("PortB");
                            portBelem2.Add(new XAttribute("Connected_BY", device.ConnectedBy));
                            deviceElem2.Add(new XAttribute("TB", device.TBType1));
                            deviceElem2.Add(new XAttribute("ParentConnectedToPort", device.ParentConnectedTo));
                            deviceElem2.Add(new XAttribute("MiniBot_minus_pin", device.MinusPin1));
                            deviceElem2.Add(new XAttribute("MiniBot_pluse_pin", device.PlusPin));
                            deviceElem2.Add(new XAttribute("FTDI_Port", device.FtdiPort));
                            deviceElem2.Add(new XAttribute("Name", device.Name));
                            deviceElem2.Add(new XAttribute("Cable", device.Cable));
                            portBelem2.Add(deviceElem2);
                            selectedElement.Add(portBelem2);
                        }
                    }
                }
            }

            if (flag == true)
            {
                if (cmbPowerMode.Text == "PowerSplitter" || cmbPowerMode.Text == "None")
                {

                    SX sx = new SX();
                    elm.Add(new XElement("Sx", new XAttribute("FTDI_port", numircFTDIPin.Value), new XAttribute("SX_power_button_pin", numircPowerPin.Value), new XAttribute("SX_SLP_S3_pin", numircs3Pin.Value), new XAttribute("SX_SLP_S4_pin", numircs4Pin.Value), new XAttribute("SX_SLP_S5_pin", numircs5Pin.Value), new XAttribute("SX_TBT_wake_N_pin", numircWakeNpin.Value), new XAttribute("SX_PCIE_wake_pin", numircWakePin.Value), new XAttribute("G3_Power_Mode", cmbPowerMode.Text)));

                }
                else
                {
                    MessageBox.Show("Please select Power mode value");
                }

                xdoc.Save(Application.StartupPath + "\\Topology.xml");
                MessageBox.Show("XML created !!!");
                Application.Exit();
            }
            else
                MessageBox.Show("You did not papulate data to XML file please fill up your data");
        }