- PR -

データセットをWriteXmlしたときの要素の出力順について

1
投稿者投稿内容
ぽち
会議室デビュー日: 2007/10/04
投稿数: 3
投稿日時: 2007-10-18 15:55
はじめて投稿いたします。
以下のようなデータセット定義(dataset1.xsd)があり、vb.netで項目に値をいれ、WriteXmlをしたとき(test.vb)結果がtest001.xmlです。
この時出力結果の項目の順番が、
<A1>
<A2>
<BB>
では無く
データセットで定義した順番の
<A1>
<BB>
<A2>
で出力をしたいのです。
いろいろと調べは下のですが明確な回答が見つからず、皆様のお知恵をお借りしたいのでよろしくお願いします。
開発環境は
WinXP ProSP2
vs.net2003
です。

--dataset1.xsd
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="Dataset1" targetNamespace="http://tempuri.org/Dataset1.xsd" elementFormDefault="qualified"
attributeFormDefault="qualified" xmlns="http://tempuri.org/Dataset1.xsd" xmlns:mstns="http://tempuri.org/Dataset1.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="Dataset1" msdata:IsDataSet="true">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="DS">
<xs:complexType>
<xs:sequence>
<xs:element name="A1" type="xs:string" minOccurs="0" />
<xs:element name="BB" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="B1" type="xs:string" minOccurs="0" fixed="no" />
</xs:sequence>
<xs:attribute name="no" type="xs:string" msdata:AutoIncrement="true" msdata:AutoIncrementSeed="0"
msdata:AutoIncrementStep="1" />
</xs:complexType>
</xs:element>
<xs:element name="A2" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>

--test.vb
Dim ds As New Dataset1
ds.DS.AddDSRow("A1", "A2")
ds.BB.AddBBRow("B1", CType(ds.DS(0), Dataset1.DSRow))
ds.BB.AddBBRow("B2", CType(ds.DS(0), Dataset1.DSRow))
ds.DS.AddDSRow("A3", "A4")
ds.BB.AddBBRow("B1", CType(ds.DS(1), Dataset1.DSRow))
ds.BB.AddBBRow("B2", CType(ds.DS(1), Dataset1.DSRow))
ds.WriteXml("C:\temp\test001.xml")

--test001.xml
<?xml version="1.0" standalone="yes"?>
<Dataset1 xmlns="http://tempuri.org/Dataset1.xsd">
<DS>
<A1>A1</A1>
<A2>A2</A2>
<BB>
<B1>B1</B1>
</BB>
<BB>
<B1>B2</B1>
</BB>
</DS>
<DS>
<A1>A3</A1>
<A2>A4</A2>
<BB>
<B1>B1</B1>
</BB>
<BB>
<B1>B2</B1>
</BB>
</DS>
</Dataset1>
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-10-25 22:16
ここ
http://msdn2.microsoft.com/ja-jp/library/system.xml.serialization.xmlelementattribute_members(VS.80).aspx

この辺から一通り読んでおいた方がいいと思う
http://msdn2.microsoft.com/ja-jp/library/7ay27kt9(VS.80).aspx
ぽち
会議室デビュー日: 2007/10/04
投稿数: 3
投稿日時: 2007-10-26 15:04
>>Jitta様
返信ありがとうございます。
教えていただいたMSDNを呼んでみます。
なにぶんXMLの知識は無いものですので、分からない無いことがありましたらまた御教授願います
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-10-26 18:15
すみません
ごめんなさい
勘違いしてました

あとで詳しいの張りますが、出力しているスキーマが変わっているので、ツールのバグを疑ってもいいかも?です
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-10-26 19:48
 sequence だから、その順番で出力されるだろう?と思ったのですが、クラスの方(Dataset1.xsd.vb)を見て下さい。BB が、プロパティとしては宣言されていません。これが原因ですかね。
コード:
(これは C# です)
[System.Diagnostics.DebuggerStepThrough()]
public class DSRow : DataRow {
    private DSDataTable tableDS;
    internal DSRow(DataRowBuilder rb) :
            base(rb) {
        this.tableDS = ((DSDataTable)(this.Table));
    }
    public string A1 {
        get {
            try {
                return ((string)(this[this.tableDS.A1Column]));
            }
            catch (InvalidCastException e) {
                throw new StrongTypingException(
                "値は DBNull であるため、取得できません。", e);
            }
        }
        set {
            this[this.tableDS.A1Column] = value;
        }
    }
    public string A2 {
        get {
            try {
                return ((string)(this[this.tableDS.A2Column]));
            }
            catch (InvalidCastException e) {
                throw new StrongTypingException(
                "値は DBNull であるため、取得できません。", e);
            }
        }
        set {
            this[this.tableDS.A2Column] = value;
        }
    }
    public bool IsA1Null() {
        return this.IsNull(this.tableDS.A1Column);
    }
    public void SetA1Null() {
        this[this.tableDS.A1Column] = System.Convert.DBNull;
    }
    public bool IsA2Null() {
        return this.IsNull(this.tableDS.A2Column);
    }
    public void SetA2Null() {
        this[this.tableDS.A2Column] = System.Convert.DBNull;
    }
    public BBRow[] GetBBRows() {    // ここ
        return ((BBRow[])(this.GetChildRows(this.Table.ChildRelations["DS_BB"])));
    }
}



 それでもやっぱり、sequence なんだから…ということで、XmlWrite を、スキーマも出力するように変更してみました。すると、スキーマ定義が変わっちゃってますね...
バグって言っていいのかなぁ?
とりあえず、KB を「スキーマ 順 変」「スキーマ sequence」「スキーマ 定義の順序が変わる」「sequence 順番が変わる」で検索かけてみましたが、それらしいものは見あたりませんでした。
コード:
<?xml version="1.0" standalone="yes"?>
<Dataset1 xmlns="http://tempuri.org/Dataset1.xsd">
  <xs:schema id="Dataset1" targetNamespace="http://tempuri.org/Dataset1.xsd"
  xmlns:mstns="http://tempuri.org/Dataset1.xsd"
  xmlns="http://tempuri.org/Dataset1.xsd"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
  attributeFormDefault="qualified" elementFormDefault="qualified">
    <xs:element name="Dataset1" msdata:IsDataSet="true">
      <xs:complexType>
        <xs:choice maxOccurs="unbounded">
          <xs:element name="DS">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="A1" type="xs:string" minOccurs="0" />
                <xs:element name="A2" type="xs:string" minOccurs="0" />
                <xs:element name="BB" minOccurs="0" maxOccurs="unbounded">
                  <xs:complexType>
                    <xs:sequence>
                      <xs:element name="B1" type="xs:string"
                      minOccurs="0" msdata:Ordinal="1" />
                    </xs:sequence>
                    <xs:attribute name="no" msdata:AutoIncrement="true"
                    type="xs:int" />
                  </xs:complexType>
                </xs:element>
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <DS>
    <A1>A1</A1>
    <A2>A2</A2>
    <BB d3p1:no="0" xmlns:d3p1="http://tempuri.org/Dataset1.xsd">
      <B1>B1</B1>
    </BB>
    <BB d3p1:no="1" xmlns:d3p1="http://tempuri.org/Dataset1.xsd">
      <B1>B2</B1>
    </BB>
  </DS>
  <DS>
    <A1>A3</A1>
    <A2>A4</A2>
    <BB d3p1:no="2" xmlns:d3p1="http://tempuri.org/Dataset1.xsd">
      <B1>B1</B1>
    </BB>
    <BB d3p1:no="3" xmlns:d3p1="http://tempuri.org/Dataset1.xsd">
      <B1>B2</B1>
    </BB>
  </DS>
</Dataset1>

Ruku
会議室デビュー日: 2007/07/05
投稿数: 6
投稿日時: 2007-10-29 10:09
たぶん、ちょうど同じ問題にぶち当たってます。ちなみに解決策ではありません。

http://msdn2.microsoft.com/ja-jp/library/system.data.dataset.getxml.aspx

ここの解説の部分に、

引用:
スキーマ インターフェイスを使用して DataSet を構築し、XML または Web サービスを使用してシリアル化した場合、列の順序が変わる可能性があります。



とあったので、そういうものなのかと妥協しました。
どうも属性(のみ?)の要素を使用すると DataTable が別に作成され、その場合にうまくいかないのかなぁと思っていますが、詳細はわかりません。

私も解決法を知りたいので、識者の方の回答を期待します。
1

スキルアップ/キャリアアップ(JOB@IT)