2009-06-18 77 views
3

我有一個XSD,我必須生成一個XML文檔發送給我工作的公司的客戶。我發送的文檔將根據此XSD架構進行驗證。創建符合XSD架構的XML文檔的最佳方式是什麼?

創建符合XSD架構的XML文檔的最佳方式是什麼?我的意思是,我正在尋找最佳實踐等。我對此很陌生,同時在這裏和那裏「谷歌搜索」,我發現人們使用XmlTextWriter,DataSet.WriteXml和其他人。

  1. DataSet.WriteXml似乎不適合我。這是我所做的:

    var ds = new DataSet(); 
    ds.ReadXmlSchema(schemaFile); 
    ds.Tables["TableName"].Rows.Add("", "", 78, true, DateTime.Now); 
    ... 
    ds.WriteXml("C:\\xml.xml"); 
    

    我發現它使用NewDataSet生成一個節點,並且節點沒有正確的順序。

  2. XmlTextWriter,我發現它有點長...但我會如果沒有其他選擇。

您認爲最好的方法是做什麼?還有其他方法可以做到嗎? 如果沒有這麼長時間,我會把模式放在這裏,如果它與問題相關。

回答

6

.NET中的主流做法是使用XML Serialization

在你的情況,我會做到這一點:

  • .XSD上也運行XSD.EXE來生成類的源代碼(XSD/C)
  • 建立自己的應用程序,利用這些生成的類。請記住,您可以通過代碼中的「部分類」技術擴展這些類,實例化一個XmlSerializer並序列化這些類實例。

例子:

鑑於此架構:

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="Foo" nillable="true" type="Foo" /> 
    <xs:complexType name="Foo"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" name="Bar" type="xs:string" /> 
     <xs:element minOccurs="0" maxOccurs="1" name="Baz" type="UntypedArray" /> 
    </xs:sequence> 
    </xs:complexType> 


    <xs:complexType name="UntypedArray"> 
    <xs:choice minOccurs="1" maxOccurs="unbounded"> 
     <xs:element name="Type1" type="Type1"     minOccurs="1" maxOccurs="1"/> 
     <xs:any  namespace="##other" processContents="lax" minOccurs="1" maxOccurs="1"/> 
    </xs:choice> 
    </xs:complexType> 


    <xs:complexType name="Type1" mixed="true"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" name="Child" type="xs:string" /> 
    </xs:sequence> 
    </xs:complexType> 
</xs:schema> 

XSD.EXE生成此源代碼:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)] 
public partial class Foo { 

    private string barField; 

    private object[] bazField; 

    /// <remarks/> 
    public string Bar { 
     get { 
      return this.barField; 
     } 
     set { 
      this.barField = value; 
     } 
    } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlArrayItemAttribute("", typeof(System.Xml.XmlElement), IsNullable=false)] 
    [System.Xml.Serialization.XmlArrayItemAttribute(typeof(Type1), IsNullable=false)] 
    public object[] Baz { 
     get { 
      return this.bazField; 
     } 
     set { 
      this.bazField = value; 
     } 
    } 
} 

/// <remarks/> 
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
public partial class Type1 { 

    private string childField; 

    private string[] textField; 

    /// <remarks/> 
    public string Child { 
     get { 
      return this.childField; 
     } 
     set { 
      this.childField = value; 
     } 
    } 

    /// <remarks/> 
    [System.Xml.Serialization.XmlTextAttribute()] 
    public string[] Text { 
     get { 
      return this.textField; 
     } 
     set { 
      this.textField = value; 
     } 
    } 
} 

在您的應用程序,你可以實例化一個Foo,然後序列化,像這樣:

Foo foo = new Foo(); 
    // ...populate foo here... 
    var builder = new System.Text.StringBuilder(); 
    XmlSerializer s = new XmlSerializer(typeof(Foo)); 
    using (var writer = System.Xml.XmlWriter.Create(builder)) 
    { 
     s.Serialize(writer, foo, ns); 
    } 
    string rawXml = builder.ToString(); 

本示例將序列化爲一個字符串。當然,你可以序列化到其他XmlWriters,你可以寫出一個文件,任何任意的流,等等。

通常我會調整序列化以省略XML聲明,省略默認的xml命名空間等等。就像這樣:

Foo foo = new Foo(); 
    // ...populate foo here... 
    var builder = new System.Text.StringBuilder(); 
    var settings = new System.Xml.XmlWriterSettings { OmitXmlDeclaration = true, Indent= true }; 
    var ns = new XmlSerializerNamespaces(); 
    ns.Add("",""); 
    XmlSerializer s = new XmlSerializer(typeof(Foo)); 
    using (var writer = System.Xml.XmlWriter.Create(builder, settings)) 
    { 
     s.Serialize(writer, foo, ns); 
    } 
    string rawXml = builder.ToString(); 

你也可以做相反的 - 圖從XML文檔到內存中的對象圖 - 使用XmlSerializer。使用Deserialize方法。

+0

Txs,我認爲它工作正常,但是我要去測試它......另一個問題,我該如何「美化」xml輸出?我的意思是...我想也有一個更人類可讀的XML ... – 2009-06-18 21:45:49

2

這麼大的參考.. http://msdn.microsoft.com/en-us/library/x6c1kb0s%28v=vs.110%29.aspx

我剛生成的類與csharp的領域:

首先,你打開Visual Studio命令提示符(程序 - > visualStudio-> visualstudioTools-> VisualstudioCommandPrompt

然後你改變你的XSD文件的目錄,然後運行以下命令:

xsd /classes /fields /language:CS MyXSDSCHEMAFILE.xsd 

(替換爲您的XSD文件名MyXSDSCHEMAFILE.xsd)

創建你的CS文件後,將其複製到所有其他CS文件是項目文件夾,並通過將其添加到該項目在Visual Studio右鍵單擊項目並添加現有項目。一旦這項工作完成後轉到您要使用你的類和初始化像這樣(類名是已在CS文件中創建的類)的代碼段:上

classname myvariablename = new classname(); // so easy :) 
// now you just fill with content 
myvariablename.whatever.andever.field = "JaWerHatDasErfunden";// you just set a field 

然後序列化爲XML(噸的例子網絡)

有用的提示: 注意,實例化並不總是XSD創建類的一部分。
確保正確創建對象以避免空指針異常。

相關問題