使用 XSD 文件在 C# 中生成 XML 文件

Posted

技术标签:

【中文标题】使用 XSD 文件在 C# 中生成 XML 文件【英文标题】:Generating XML file in C# using XSD file 【发布时间】:2021-01-28 11:01:05 【问题描述】:

为了通过 C# 代码以 xml 格式导出我的数据,我使用了以下建议。但是我的 xml 格式和 xsd 不同,我无法生成它。

【相关解决方案】https://***.com/a/6530496/3102147

我的xsd文件如下:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="list">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="Sam" maxOccurs="unbounded" minOccurs="0"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="Sam">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="UploadCode" type="xs:string" minOccurs="0"/>
                <xs:element name="UploadId" type="xs:string" minOccurs="0"/>
                <xs:element name="Lab" type="xs:string"/>
                <xs:element name="Job" type="xs:string"/>
                <xs:element name="Scheme" type="xs:string"/>
                <xs:element name="SampleType" type="xs:string"/>
                <xs:element name="SampleId" type="xs:string"/>
                <xs:element name="Id" type="xs:string"/>
                <xs:element name="qcOccur" type="xs:byte" minOccurs="0"/>
                <xs:element name="InstrumentName" type="xs:string"/>
                <xs:element name="InstrumentRunWith" type="xs:string"/>
                <xs:element name="AnalDate" type="xs:string" minOccurs="0"/>
                <xs:element name="AnalTime" type="xs:string" minOccurs="0"/>
                <xs:element name="Analyst" type="xs:string" minOccurs="0"/>
                <xs:element name="ResultMode" type="xs:string"/>
                <xs:element name="Dilution" type="xs:string" minOccurs="0"/>            
                <xs:element ref="Analyses"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="Analyses">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="Ana" maxOccurs="unbounded" minOccurs="0"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="Ana">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Analysis" type="xs:string"/>
                <xs:element name="Parameter" type="xs:string" minOccurs="0"/>
                <xs:element name="Result" type="xs:string"/>
                <xs:element name="AnalDate" type="xs:string"/>
                <xs:element name="AnalTime" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

我的xml输出文件应该如下:

<list>
  <Sam>
    <Lab>ZAORK_M</Lab>
    <Job>ORK20-01536</Job>
    <Scheme>GO_FAG50V</Scheme>
    <SampleType>Unknown</SampleType>
    <SampleId>ORK20-01536.001</SampleId>
    <Id>ORK_S0003725727</Id>
    <InstrumentName>B0001_OFFLINE_WEIGHT</InstrumentName>
    <InstrumentRunWith>MKY386</InstrumentRunWith>
    <AnalDate>3/10/2019|dd/MM/yyyy</AnalDate>
    <AnalTime>8:33:23 AM|hh:mm:ss a</AnalTime>
    <Analyst>PHILLIP_HARRIS</Analyst>
    <ResultMode>WEIGHT_VOLUME</ResultMode>
    <Analyses>
      <Ana>
        <Analysis>Weight</Analysis>
        <Result>0.1111</Result>
        <AnalDate>3/10/2019|dd/MM/yyyy</AnalDate>
        <AnalTime>8:33:23 AM|hh:mm:ss a</AnalTime>
      </Ana>
      <Ana>
        <Analysis>Volume</Analysis>
        <Result>0.1</Result>
        <AnalDate>3/10/2019|dd/MM/yyyy</AnalDate>
        <AnalTime>8:33:23 AM|hh:mm:ss a</AnalTime>
      </Ana>
    </Analyses>
  </Sam>
</list>

我的代码如下:

var Sample = new Sam  UploadCode = "test1", UploadId = "test2" ;
            var Analysis = new Ana  Analysis = "Test2", Result = "123" ;

            var serializer1 = new XmlSerializer(typeof(Sam));
            using (var stream = new StreamWriter("C:\\test.xml"))
            
                serializer1.Serialize(stream, Sample);
            

我遇到的问题是我无法在 sam 之前创建列表节点,也无法将 Analysis 放在 sam 下,Ana 放在 Analysis 下。

我无法理解如何修复我的代码,以便它正确知道哪个子节点如何应用于正确的父节点。如果有人知道如何解决此问题,请提供帮助。

【问题讨论】:

【参考方案1】:

您的代码中缺少一些实际生成消息的步骤。从 xsd 生成的 cs 文件有一个名为 list() 的类。这是您想要创建完整的 xml 结构时的起点。 在列表下,您有一个名为 Sam 的重复组,xsd.exe 将其转换为一个数组。 Xsd.exe 不知道列表。所以接下来你需要做的是定义 Sam 将出现在 xml 文件中的情况。对于每个 Sam,还有一个名为 Analysis 的数组也需要定义。 如果你这样做,然后将内容序列化为一个 xml 文件,你将得到你想要的。但请记住,您需要填写类中的所有元素。如果不这样做,序列化程序将采用默认值,数字字段为 0,字母数字字段为 null。 null 值未序列化,因此该元素被遗漏,从而使您的 xml 内容无效。

以下示例有效,但缺少很多元素

var list = new list();
list.Sam = new Sam[1];
            
var sample = new Sam  UploadCode = "test1", UploadId = "test2", Analyses = new Ana[1];
var analysis = new Ana  Analysis = "Test2", Result = "123" ;

sample.Analyses[0] = analysis;
list.Sam[0] = sample;

var serializer1 = new XmlSerializer(typeof(list));
using (var stream = new StreamWriter("test.xml"))

   serializer1.Serialize(stream, list);

【讨论】:

非常感谢它的魅力。不过我还有一个问题,是否可以遍历所有节点并在循环中动态设置它们的值?如果是的话,你能告诉我怎么做吗? 我不确定你的实际意思是什么,但如果你想用数据填充元素,我希望你需要某种映射例程。你需要遍历你的源来填充列表。 别担心,我明白了。非常感谢您的帮助

以上是关于使用 XSD 文件在 C# 中生成 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章

使用 XSD.exe 的多个版本 C# 类/XSD

为 C# 生成的 XML 文档的 XSD? [关闭]

如何从数据库表中生成xml文件?

用xmlspy把xsd怎么转换成xml

在 C# 中针对引用的 XSD 验证 XML

在不修改 C# XSD 类的情况下向 XML 序列化添加前缀和命名空间