2016-08-29 13 views
2

オブジェクトに逆シリアル化しようとしている反復型の入力XML文字列が<row>ですが、最後の行を除くすべての行は無視されます。どんな助けもありがとう。C#反復タグを使用してXMLを逆シリアル化する

例として、逆シリアル化後に、私が手オブジェクトは、次のとおりです。

object.command[0].userTable = 
    {OCI.OCITable} 
     colHeading: {string[3]} 
     colHeadingField: {string[3]} 
     row: {string[3]} 
     rowField: {string[3]} 

これは、このオブジェクトの唯一の1行がありますので、間違っているが、入力されたXML文字列に4 <row>があるべきですこのように:

<?xml version="1.0" encoding="ISO-8859-1" ?> 
    <BroadsoftDocument protocol="OCI" xmlns="C" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <sessionId xmlns="">feajiofefeaij</sessionId> 
    <command echo="" xsi:type="UserGetListInServiceProviderResponse" xmlns=""> 
    <userTable> 
     <colHeading>User Id</colHeading> 
     <colHeading>Group Id</colHeading> 
     <colHeading>Name</colHeading> 
     <row> 
      <col>1</col> 
      <col>A</col> 
      <col>Smith</col> 
     </row> 
     <row> 
      <col>2</col> 
      <col>A</col> 
      <col>John</col> 
     </row> 
     <row> 
      <col>3</col> 
      <col>B</col> 
      <col>James</col> 
     </row> 
     <row> 
      <col>4</col> 
      <col>B</col> 
      <col>Lisa</col> 
     </row> 
    </userTable> 
    </command> 
    </BroadsoftDocument> 

私は直列化復元をやっている方法は次のとおりです。

MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(responseString)); 
XmlSerializer ser = new XmlSerializer(typeof(OCIMessage)); 
OCIMessage response = (OCIMessage)ser.Deserialize(memStream); 

かつ自動的OCITableクラスxsd.exeによって生成されたC#クラスはこれです:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "C")] 
public partial class OCITable 
{ 

    private string[] colHeadingField; 
    private string[] rowField; 

    [System.Xml.Serialization.XmlElementAttribute("colHeading", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] 
    public string[] colHeading 
    { 
     get 
     { 
      return this.colHeadingField; 
     } 
     set 
     { 
      this.colHeadingField = value; 
     } 
    } 

    [System.Xml.Serialization.XmlArrayAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] 
    [System.Xml.Serialization.XmlArrayItemAttribute("col", typeof(string), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = false)] 
    public string[] row 
    { 
     get 
     { 
      return this.rowField; 
     } 
     set 
     { 
      this.rowField = value; 
     } 
    } 
} 
+2

XmlArrayItemAttribute(すべての場所)からXmlElementへの行と列の変更。 – jdweng

+0

@jdwengあなたはその違いを説明できますか? – Synia

+0

XmlArrayはのような2番目のタグを作成しますが、XElementのみが作成します jdweng

答えて

2

主な問題は、XMLに、<row><col>要素は2Dギザギザアレイである、ということである:外があり、繰り返し<row>要素のセットは、それぞれが文字列値を持つ<col>要素の内部反復集合を含んでいます。しかし、あなたは、文字列の1次元配列として、これをモデル化しているあなたのOCITableクラスで:

public string[] row { get; set; } 

これはのみ外<row>要素が可能になります。解析中に複数の<row>要素が検出された場合、XmlSerializerは、以前の値を後で上書きします。これはあなたが見ているものです。

行と列の要素のネストされた階層構造を捉えるためには、あなたの代わりのような何かをする必要があります:あなたがしなければ、あなたはすなわち、C# xml serialization remove jagged array element nameで説明した問題が発生します、しかし

public string[][] row { get; set; } 

をそのXmlSerializerはいつものように、余分の外側コンテナ部材と2Dジャグ配列をシリアライズされます

<row> 
    <col> 
     <string>a</string> 
    </col> 
    <col> 
     <string>b</string> 
    </col> 
</row> 

したがってこれも動作しません。

代わりに、あなたがそうのように、あなたのrowメンバー文字列の1次元配列を含み、中間クラスの単純な配列を作成する必要があります。

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "C")] 
public partial class OCITable 
{ 
    private string[] colHeadingField; 

    [System.Xml.Serialization.XmlElementAttribute("colHeading", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] 
    public string[] colHeading 
    { 
     get 
     { 
      return this.colHeadingField; 
     } 
     set 
     { 
      this.colHeadingField = value; 
     } 
    } 

    [System.Xml.Serialization.XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] 
    public OCITableRow [] row { get; set; } 
} 

public class OCITableRow 
{ 
    [System.Xml.Serialization.XmlElementAttribute("col", Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = false)] 
    public string[] col { get; set; } 
} 

両方rowcol配列を示すために[XmlElement]でマークされています外部コンテナ要素を持たない要素の繰り返しシーケンスとしてシリアル化する必要があります。

上記のクラスでは、<userTable>要素を逆シリアル化できます。サンプルfiddle

+0

XSDスキーマから生成した後にC#クラスを微調整する必要があるのは好奇心ですか?私はWebサービスによって提供されるスキーマを使ってVisual Studioに付属しているxsd.exeを使ってこれらのクラスを生成しました。この問題の原因が不完全なスキーマだと思うか、クラスジェネレータを適切に構成しなかったのですか、または生成後に手でクラスを微調整する必要があるのが普通ですか? (公平に生成されたコードは 'string [] []'を持っていましたが、2D配列は私のアプリケーションをクラッシュさせていたので1D配列に変更しました) – Synia

+0

@Synia - 通常は必要ありません。たぶん、xsd.exeには、[ここに記載されているような]コンテナ要素のないギザギザの配列に問題があります(https://stackoverflow.com/questions/9135445/c-sharp-xml-serialization-remove-jagged-array-element-名)? – dbc

+0

Synia - BroadSoft/BroadWorksとJavaが大好きです!私たちはちょうど同じ問題に遭遇し、他の記事に基づいてこの同じルートを下っていました。 – JGlass

関連する問題