簡體   English   中英

C#/.net 從數據集中調用 XMLWriter() function 時保留架構和 XML

[英]C#/.net Preserve Schema and XML when calling XMLWriter() function from dataset

我有一個 xml 文件

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfLocations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Location xsi:type="JointLocation">
    <Name>Example Location</Name>
    <Index>0</Index>
    <ZClearance>0</ZClearance>
    <Joint1>100</Joint1>
    <Joint2>200</Joint2>
    <Joint3>200</Joint3>
    <Joint4>200</Joint4>
    <Joint5>200</Joint5>
    <joint6>0</joint6>
    <Joint6>0</Joint6>
  </Location>
</ArrayOfLocations>

我將此文件加載到數據集中,然后加載到 DataGridView。 從那個 DataGridView 我可以添加新的 Location 元素,或者編輯現有的 Location 元素並保存。 當我保存時,我正在這樣做

string path = filePathBox.Text;
DataSet ds = (DataSet)dataGridView1.DataSource;
ds.WriteXml(filePathBox.Text);

保存后,XML 文件看起來像

<?xml version="1.0" standalone="yes"?>
<ArrayOfLocations>
  <Location>
    <Name>Example Location</Name>
    <Index>0</Index>
    <ZClearance>0</ZClearance>
    <Joint1>100</Joint1>
    <Joint2>200</Joint2>
    <Joint3>200</Joint3>
    <Joint4>200</Joint4>
    <Joint5>200</Joint5>
    <joint6>0</joint6>
    <Joint6>0</Joint6>
  </Location>
</ArrayOfLocations>

如您所見,xsi 和命名空間已被刪除。 我想保留這些屬性。

到目前為止,我已嘗試將作為附加參數添加到 WriteXML():

ds.WriteXML(filepath, XmlWriteMode.WriteSchema)

但是,這會造成很大的混亂,並且仍然無法保持我想要保留的初始格式。 有小費嗎?

一個簡單的示例向我們展示了ReadXML / WriteXML將丟失您感興趣的架構信息

using (FileStream fs = new FileStream("D:\\Workspace\\FormTest\\input.xml", FileMode.Open))
{
    DataSet ds = new DataSet();
    ds.ReadXml(fs);
    ds.WriteXml(Console.Out);
}

給我們

<ArrayOfLocations>
  <Location>
    <Name>Example Location</Name>
    <Index>0</Index>
    <ZClearance>0</ZClearance>
    <Joint1>100</Joint1>
    <Joint2>200</Joint2>
    <Joint3>200</Joint3>
    <Joint4>200</Joint4>
    <Joint5>200</Joint5>
    <joint6>0</joint6>
    <Joint6>0</Joint6>
  </Location>
</ArrayOfLocations>

我發現恢復此架構信息的最佳方法是Deserialize數據。 它不漂亮,但對我有用:

XmlSerializer s = new XmlSerializer(typeof(ArrayOfLocations));
ArrayOfLocations fix = new ArrayOfLocations();
using (FileStream fs = new FileStream("D:\\Workspace\\FormTest\\input.xml", FileMode.Open))
{
    DataSet ds = new DataSet();
    ds.ReadXml(fs);
    string xml = ds.GetXml();
    ArrayOfLocations input = (ArrayOfLocations)s.Deserialize(new StringReader(xml));
    
    foreach(var location in input)
    {
        fix.Add(new JointLocation()
        {
            Name = location.Name,
            ...
            Joint6 = location.Joint6 
        });
    }
}

XmlTextWriter xtw = new XmlTextWriter(Console.Out);
xtw.Formatting = Formatting.Indented;
s.Serialize(xtw, fix);

當然,您需要創建 model 您的架構的類以便反序列化:

public class Location
{
    public string Name { get; set; }
    ...
    public byte Joint6 { get; set; }
}

public class JointLocation : Location { }

[XmlInclude(typeof(JointLocation))]
[XmlRoot("ArrayOfLocations")]
public class ArrayOfLocations : List<Location> { }

請注意以下問題

  1. 您需要定義一個JoinLocation class,在XmlInclude下指定該類型,並手動修復您的 object 以符合您想要 output 到的架構。
  2. 您將需要使用XmlTextWritter來尊重縮進

這一切都應該為您提供所需的 output:

<?xml version="1.0" encoding="Codepage - 437"?>
<ArrayOfLocations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Location xsi:type="JointLocation">
    <Name>Example Location</Name>
    <Index>0</Index>
    <ZClearance>0</ZClearance>
    <Joint1>100</Joint1>
    <Joint2>200</Joint2>
    <Joint3>200</Joint3>
    <Joint4>200</Joint4>
    <Joint5>200</Joint5>
    <Joint6>0</Joint6>
  </Location>
</ArrayOfLocations>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM