You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XSD转DataSet再生成XML时如何保留元素顺序通过XSD校验?

解决方案

DataSet的GetXml()方法本身不会保留XSD定义的元素顺序,因为它基于数据表结构输出:先输出所有列(简单类型),再输出子表对应的复杂类型元素。以下是两种可行的解决方法:

方法1:使用XmlWriter自定义序列化逻辑

直接基于DataSet的数据,按照XSD规定的顺序手动写入XML元素,严格控制输出顺序,这是最直接可靠的方式。

修正后的代码

var schemaString = @"<xs:schema xmlns:xs=""http://www.w3.org/2001/XMLSchema"" >
<xs:element name=""Person"">
  <xs:complexType>
    <xs:sequence>
      <xs:element name=""Ttl"" minOccurs=""0"">
        <xs:simpleType>
          <xs:restriction base=""xs:string"">
            <xs:maxLength value=""4"" />
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
     <xs:element minOccurs=""0"" maxOccurs=""1"" name=""Address"">
       <xs:complexType>
         <xs:sequence>
           <xs:element minOccurs=""1"" maxOccurs=""4"" name=""Line_1"">
             <xs:simpleType>
               <xs:restriction base=""xs:string"">
               <xs:maxLength value=""35"" />
             </xs:restriction>
             </xs:simpleType>
           </xs:element>
           <xs:element minOccurs=""1"" maxOccurs=""4"" name=""Line_2"">
             <xs:simpleType>
               <xs:restriction base=""xs:string"">
                    <xs:maxLength value=""35"" />
                </xs:restriction>
             </xs:simpleType>
           </xs:element>
           <xs:element minOccurs=""0"" maxOccurs=""1"" name=""PostCode"">
             <xs:simpleType>
                 <xs:restriction base=""xs:string"">
                   <xs:maxLength value=""35"" />
                 </xs:restriction>
             </xs:simpleType>
           </xs:element>
         </xs:sequence>
       </xs:complexType>
     </xs:element>
      <xs:element name=""Fore"" maxOccurs=""2"">
        <xs:simpleType>
          <xs:restriction base=""xs:string"">
            <xs:maxLength value=""35"" />
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
      <xs:element name=""Sur"">
        <xs:simpleType>
          <xs:restriction base=""xs:string"">
            <xs:maxLength value=""35"" />
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
     
    </xs:sequence>
  </xs:complexType>
</xs:element>
</xs:schema>";

var schemaReader = XmlReader.Create(new StringReader(schemaString));
var dataSet = new DataSet();
dataSet.ReadXmlSchema(schemaReader);

dataSet.Tables["Person"].Rows.Add("Mr", "John",  "Smith");
dataSet.Tables["Address"].Rows.Add("Street", "Suburb", "1234");
dataSet.Tables["Address"].Rows[0].SetParentRow(dataSet.Tables["Person"].Rows[0]);

// 手动生成符合顺序的XML
var sb = new StringBuilder();
using var writer = XmlWriter.Create(sb, new XmlWriterSettings { Indent = true });

writer.WriteStartElement("NewDataSet");
foreach (DataRow personRow in dataSet.Tables["Person"].Rows)
{
    writer.WriteStartElement("Person");
    
    // 严格按照XSD sequence的顺序输出元素
    writer.WriteElementString("Ttl", personRow["Ttl"]?.ToString());
    
    // 输出Address子元素
    var addressRows = personRow.GetChildRows(dataSet.Relations[0]);
    if (addressRows.Length > 0)
    {
        var addressRow = addressRows[0];
        writer.WriteStartElement("Address");
        writer.WriteElementString("Line_1", addressRow["Line_1"]?.ToString());
        writer.WriteElementString("Line_2", addressRow["Line_2"]?.ToString());
        writer.WriteElementString("PostCode", addressRow["PostCode"]?.ToString());
        writer.WriteEndElement();
    }
    
    writer.WriteElementString("Fore", personRow["Fore"]?.ToString());
    writer.WriteElementString("Sur", personRow["Sur"]?.ToString());
    
    writer.WriteEndElement();
}
writer.WriteEndElement();

var validXml = sb.ToString();
Console.WriteLine(validXml);

生成的符合校验要求的XML

<NewDataSet>
  <Person>
    <Ttl>Mr</Ttl>
    <Address>
      <Line_1>Street</Line_1>
      <Line_2>Suburb</Line_2>
      <PostCode>1234</PostCode>
    </Address>
    <Fore>John</Fore>
    <Sur>Smith</Sur>
  </Person>
</NewDataSet>

方法2:XSLT转换(适合复杂场景)

如果需要处理大量复杂结构,可以先让DataSet输出包含Schema的XML,再编写XSLT样式表将元素重新排序为XSD要求的顺序。这种方式步骤较多,但适合批量处理场景。


内容的提问来源于stack exchange,提问作者Murray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 17:45:53