2009-06-18 6 views
3

私はXSDを持っており、私が働いている会社の顧客に送るXML文書を生成する必要があります。送信するドキュメントは、このXSDスキーマに対して検証されます。XSDスキーマに準拠したXML文書を作成する最良の方法は何ですか?

XSDスキーマに準拠したXML文書を作成する最適な方法は何ですか?つまり、ベストプラクティスなどを探しています。私はこれを初めて勉強しています。ここでは "Googling"の間、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/C)のソースコードを生成するために、.XSDにすぎXsd.exeでは実行。これらのクラスを「部分クラス」テクニック
  • で拡張し、XmlSerializerをインスタンス化し、クラスインスタンスをシリアル化することができます。

例:

はこのスキーマを考える:あなたはFooのをインスタンス化して、シリアル化することができ、あなたのアプリに

[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; 
     } 
    } 
} 

、:

<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では、このソースコードを生成このように:

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(); 

この例では、文字列にシリアル化されています。もちろん、他のXmlWriterにシリアライズすることも、ファイルに書き込むことも、任意のストリームに書き出すことなどもできます。

通常、XML宣言を省略するためにシリアライズを調整し、デフォルトの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(); 

また、逆の操作を行うことができますのXmlSerializerを使用します。 Deserializeメソッドを使用します。

+0

Txs、私はそれがうまくいったと思うが、私はそれをテストしようとしている...別の質問、どのように私はXML出力を美しくすることができますか?私は...もっと人間が読めるXMLを持っていたいと思っています。 –

+0

は "美化"という言葉によって決まります。もしあなたが "インデント"を意味するならば、上記の2番目のコードスニップはインデントされたXML出力を提供します。他の何かを意味するなら、plsは説明する。 – Cheeso

+0

ええ、私はインデント、感謝を意味...私はすでにそれを読んで! –

2

私が少し前に書いた投稿は、あなたにとって興味深いかもしれません。私はBizTalkを使って作業しなければならず、XSDからクラスを生成し、そのクラスをワイヤ(wa-la XML)でシリアライズするとかなりうまくいったことがわかりました。

http://blog.andrewsiemer.com/archive/2008/04/30/accepting-xmldocuments-from-biztalk-de-serializing-them-to-xsd-generated-serializable.aspx

これは、クラスなどのデータとそれと一緒に行くすべての特典を操作できます。そして、それは完全にXMLライターをバイパスすることができます!

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 

他のすべてのCSファイルがあるプロジェクトフォルダにコピーし、あなたのCSファイルが作成された後

(あなたのXSDファイル名でMyXSDSCHEMAFILE.xsdを置き換え)とによって、Visual Studioでプロジェクトに追加しますプロジェクトを右クリックして既存の項目を追加します。上の例の(トンを

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

はその後、XMLとしてシリアル化:それはあなたのクラスを使用し、(クラス名がCSファイルで作成されたクラスである)このように初期化したいあなたのコードセグメントに行くを完了するとWeb)

役に立つヒント: インスタンス化は必ずしもxsd作成クラスの一部ではないことに注意してください。
ヌルポインタの例外を避けるために、オブジェクトを適切に作成してください。

関連する問題