PR

XSDがどのような構造であればExcelでエクスポートできるのか?-その1

XMLの話題
この記事は約33分で読めます。

「Excel Tips」ではExcelを使用していて気付いたことを取り上げて行きます。

ExcelでXMLファイルを読み込む(インポート)際のXMLスキーマファイル(.xsd)の扱いについて3回目に渡ってご説明してきましたが、今回は2回に渡り、読み込み(インポート)ではなく書き出し(エクスポート)についてご説明いたく存じます。

Excelでは「複雑なXMLファイルはエクスポートできない」ように言われていますが「実際はどうなのか?」について動かせるサンプルを使いながら「できる・できない」の線引きを探ってみたいと思います。

ただし基本的に「ほぼほぼエクスポートする事はできない」のは間違いありません。

なお今回は、どのようなスキーマ構造である場合に「エクスポートできるか・できないか」についてご説明いたします。

と言いますのは『「階層リスト」に表示される項目を「どのようにセルに対応付けするか?」』によっても「エクスポートできる・できない」が発生します。

この「セルに対応付けする」機能は使いますが、一部の項目だけをエクスポートする事は対象にしていませんので、あらかじめお含み置きください。

Excel 2016バージョン2108(ビルド 14228.20348)を使用しています。

スポンサーリンク

今回使用するサンプルデータについて

Microsoft Docsには様々な製品のドキュメントがありますが、その中のひとつに「Visual StudioのXMLツール」があり、そこに下記3つのサンプルXSDファイルが掲載されています。

  • シンプルなスキーマ
    • 今回使用します。
    • リンク先:https://docs.microsoft.com/ja-jp/visualstudio/xml-tools/sample-xsd-file-simple-schema?view=vs-2019
  • 購買発注書のスキーマ
    • 次回使用します。
    • リンク先:https://docs.microsoft.com/ja-jp/visualstudio/xml-tools/sample-xsd-file-purchase-order-schema?view=vs-2019
  • リレーションシップ
    • リンク先:https://docs.microsoft.com/ja-jp/visualstudio/xml-tools/sample-xsd-file-relationships?view=vs-2019

なお リレーションシップのサンプルには読み込み(インポート)の第2回でご説明した「Excelではサポートされてないスキーマ構造」substitutionGroupが使われているため使用しません。

書き出し(エクスポート)の第1回目の今回は「シンプルなスキーマ」を使ってご説明いたします。

なお「シンプルなスキーマ」を上記サイト上でコピーをしてから、ローカル環境にファイルを作り保存します。この時のファイル名を今回は「sample-01.xsd」としています。

このスキーマファイルの構造は下記のようになります。

緑色の文字は属性を表しています。

ABC
1PurchaseOrder
2OrderDate
3ShipTo
4country
5name
6street
7city
8state
9zip
10BillTo
説明
←購買注文。ルート要素
←注文日
←送り先。maxOccurs=”2″
←国
←送り先名
←番地
←都市
←州
←郵便番号
←請求先
…子要素はShipToと同じため省略

「XMLの対応付け…」でXMLスキーマファイルを選択し、すべての項目をセルに対応付ける

読み込み(インポート)の第3回で操作方法をご説明していますので詳しくはそちらをご参照いただければ幸いです。

今回は簡単に流れをご紹介いたします。

①スキーマファイルsample-01.xsdを選択します。

②「XMLの対応付け」ウインドウでOKボタンをクリック

③「階層リスト」で、すべての項目をセルに対応付けします。

④範囲を確認してOKボタンをクリック

以上ですべての項目をセルに対応付けるまでの操作は完了になります。

対応付けたセルがエクスポートできる構造か?確認する

「エクスボートできるか?」は実際にXMLデータをインポートしなくても確認する事ができます。

①「XMLソース」ウインドウの下の方に赤枠で囲んだ「エクスポートする対応付けの確認…」というリンクが表示されていますので、リンクをクリックします。

②するとメッセージボックスが開いて「エクスポートできる・できない」の判定が表示されます。

なんと「シンプルなスキーマ」でありながら、すべての項目をセルに対応した今回のケースでは「例外的なデータ」のためにエクスポートできない事が解ります。

OKボタンでメッセージボックスを閉じます。

本来であれば、ここで「エラー内容」をご説明する必要がありますが、説明は後回しにして今回のケースでの回避先を先にご紹介いたします。

セルに対応付けする際に項目を分ける事でエクスポートできる場合がある

今回の「シンプルなスキーマ」の中にある「ShipTo要素」はmaxOccursが2に設定されています。

先に結論を述べる事になりますが、実はExcelでエクスポートできない理由の多くはこのmaxOccursの設定が関係しています。この詳細は後段でご説明いたします。

①先ほどはすべての項目を1回でセルに対応付けしましたが、今回は「階層リスト」でmaxOccursが設定されていない「OrderDate属性」と「BillTo要素」をまとめて選択(ctrlキーを押しながら選択)してセルに対応付けします。

②範囲を確認してOKボタンをクリック

③対応付けしたセル範囲には青色の枠線が表示されていますが、実はこれはXMLファイルを読み込んだ時に対象となるレコードが1件である事を表しています。

次に残っている「ShipTO要素」を「階層リスト」で選択しセルに対応付けします。貼り付け先として今回は「I1セル」を選択しています。Excelの表やテーブルは1セルは間を空けないと同じ書式を設定しようとします。そのため1セルは空ける必要はありますが、それ以外は②の範囲と重なり合わなければどこでも選択できます。

④範囲を確認してOKボタンをクリック

⑤対応付けしたセル範囲がテーブルになっていますが、これはXMLファイルを読み込んだ時に対象となるレコードが複数ある事を表しています。

ここで「エクスポートする対応付けの確認…」リンクをクリックしますが、この時の「階層リスト」の選択状態は関係しません。

⑥「階層リスト」ですべての項目を選択した状態でも、メッセージボックスには「エクスポート可能です」と表示されます。

「エクスポート可能です」と言われると、「実際にXMLファイルを読み込んだ時にどうなるのか?」を確認したくなります。

そこで次の章でサンプルのXMLファイルを作成して実際に読み込んでみます。

「どのようにエクスポートするのか?」をサンプルXMLファイルで確認

内容としては架空ですが、Micorosoftの米国のセールスオフィスの住所情報をもとにsample-01.xmlというファイル名で次のようなサンプルデータを作成しました。

※スキーマファイルではcountry属性は「US」固定に設定されていますが、12行目にわざと「JP」と入力してありますのでご注意ください。理由は次の章でご説明いたします。

<?xml version="1.0" encoding="UTF-8"?>
<PurchaseOrder OrderDate="2021-09-20" xmlns="http://tempuri.org/PurchaseOrderSchema.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!--    xsi:schemaLocation="http://tempuri.org/PurchaseOrderSchema.xsd simple-01.xsd">-->
 <ShipTo country="US">
  <name>Corporate Sales Office: Boise</name>
  <street>401 W. Front Street, Suite 600</street>
  <city>Boise</city>
  <state>ID</state>
  <zip>83702</zip>
 </ShipTo>
 <ShipTo country="JP">
  <name>Corporate Sales Office: San Francisco</name>
  <street>555 California, Suite 200</street>
  <city>San Francisco</city>
  <state>CA</state>
  <zip>94104</zip>
 </ShipTo>
 <BillTo country="US">
  <name>Corporate Sales Office: Sacramento</name>
  <street>1415 L Street, Suite 200</street>
  <city>Sacramento</city>
  <state>CA</state>
  <zip>95814</zip>
 </BillTo>
</PurchaseOrder>

sample-01.xmlの読み込みからエクスポートまでの流れをご説明いたします。

①リボン赤枠のインポートから、「XMLのインポート」ウインドウを開き、sample-01.xmlを選択し「開く」ボタンをクリックします。

②XMLファイルからデータが読み込まれて、それぞれのセル範囲に表示されます。

ここでリボンのエクスポートをクリックするのですが、もしもエクスポートに際してスキーマファイルの規制を反映する場合は③を先に設定する必要があります。

③リボンの「対応付けのプロパティー」からウインドウを開き、赤枠「インポートまたはエクスポート時にスキーマに対してデータを検証する」にチェックを入れて、OKボタンをクリックします。

④エクスボートする先を選択しファイル名を入力します。

ここでは「sample-01e」としています。

⑤③でチェックを入れた場合は、このようなメッセージボックスが表示されます。

詳細ボタンをクリックして内容を確認します。

⑥赤下線に書かれた内容は、sample-01.xmlの12行目でわざと「JP」と入力した箇所に該当しています。

なおエクスポートしたファイルにも「JP」のままで出力されますので、修正が必要です。

この操作により、sampe-01e.xmlファイルがエクスポートされますが、実際の内容は次のようになります。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns1:PurchaseOrder xmlns:ns1="http://tempuri.org/PurchaseOrderSchema.xsd" OrderDate="2021-09-20">
	<ns1:ShipTo country="US">
		<ns1:name>Corporate Sales Office: Boise</ns1:name>
		<ns1:street>401 W. Front Street, Suite 600</ns1:street>
		<ns1:city>Boise</ns1:city>
		<ns1:state>ID</ns1:state>
		<ns1:zip>83702</ns1:zip>
	</ns1:ShipTo>
	<ns1:ShipTo country="JP">
		<ns1:name>Corporate Sales Office: San Francisco</ns1:name>
		<ns1:street>555 California, Suite 200</ns1:street>
		<ns1:city>San Francisco</ns1:city>
		<ns1:state>CA</ns1:state>
		<ns1:zip>94104</ns1:zip>
	</ns1:ShipTo>
	<ns1:BillTo country="US">
		<ns1:name>Corporate Sales Office: Sacramento</ns1:name>
		<ns1:street>1415 L Street, Suite 200</ns1:street>
		<ns1:city>Sacramento</ns1:city>
		<ns1:state>CA</ns1:state>
		<ns1:zip>95814</ns1:zip>
	</ns1:BillTo>
</ns1:PurchaseOrder>

結果的にXMLファイルとしては、別々のセル範囲に対応付けされたデータがスキーマファイルに従って一つにまとめられて出力されているので、形状としては元のsampl-01.xmlファイルと同じになります。

ただしXMLファイルの出力の仕方がExcel特有な形になっていますので注意が必要です。

主な違いとして下記のような点が挙げられます。

  • XML宣言
    • standalone属性が付与されていますが、デフォルト値はyesなので省略できます。
  • ルート要素(PurchaseOrder)
    • 全面的に書き換えられています。
    • 接頭辞はnsX(Xは数値)になります。
      • 元のXMLファイルがxmlnsになっている場合でも、xmlns:nsXに書き換わっていますので注意が必要です。(元のXMLファイルは読み込めるのにエクスポートしたXMLファイルが読み込めない時はxmlnsに戻して見てください)
    • スキーマ文書を特定する名前空間(xmlns:xsi)は削除されます。
  • インデントはタブで設定されている。
  • 空タグは<要素名/>の形式で出力される。

ところで今回のサンプルでは1つのレコードの場合でしたが、これが複数レコードになった場合にはどのような動きになるのでしょうか?

2つのセル範囲がまとめられて出力できるようには思えませんが…

この点につきましては、まずはペンディングにしている「エクスポートできない時のエラー内容」についてご説明をした後、ご紹介したく存じます。

XMLスキーマの構造によりエクスポートできない場合

Microsoft Officeサポートに「XMLデータをエクスポートする」際の注意事項をまとめたページがあります。

最初に書かれているのは物理的な制約として「Excel から XML にエクスポートする場合、保存されるのは最大で 65,536 行」になる点です。

この点もさることながら、このページで注意しなければならないのは折りたたみメニューになっている「ブック内のXMLの対応付けをエクスポートできない」の内容です。

書かれている内容は大きく2つのパートに分けて構成されているのですが、なかなか表現が難解なので2つの内容を1つづつ確認をして行きます。

①対応付けられた要素とその他の要素との関係を維持できない場合にはエクスポートできません

この「関係を維持できない場合」という表題の内容は、前章でご説明した「2つのセル範囲に分けて対応付けしたものが、1つにまとめられてエクスポートされた」例から判断すると、何となく意図する内容が見えてくるような気がします。

続けて「次のような場合には、この関係を維持できない可能性があります。」と書かれていて、以降4つの場合が記載されています。

ただし本テーマでは「一部の項目だけをエクスポートする事は対象にしていません」としているので、2番目から4番目の場合については説明を割愛いたします。

一番最初の場合につきましては、色々と示唆に富んだ内容になっているため、ここで詳しく見て行くことにします。

対応付けられている要素のスキーマ定義が、次の属性を持つsequence要素の中に含まれている場合

「次の属性」の説明に入る前に sequence要素について簡単に触れておきます。

sequence要素は「要素の出現する順番を指定」するために使われていますが、sequence要素以外で「出現する順番に関する要素」としてはchoice要素とall要素があります。

これらの詳しい説明は下記「TECHSCORE」のページをご参照いただければ幸いです。

「次の属性」を下記に引用いたしますが、次の2つが条件になります。

※なお2つ目の条件に書かれている「別のcompositor要素」に関しては本章後段でご説明いたします。

  • maxoccurs 属性に1以外の値が指定されている。
  • シーケンスに直接の子要素が2つ以上定義されているか、または別のcompositor要素が直接の子要素として含まれている。

この2つの条件は「or条件なのか?、and条件なのか?」ですが、本章のタイトルに書かれている「次の属性を持つsequence要素」から判断すると、これはand条件になる認識です。

ここで、『すべての項目をセルに対応付けた時に発生した「例外的なデータ」のためにエクスポートできなかったエラー』の説明に戻ります。

「シンプルなスキーマ」からPurchaseOrderTypeを抜粋すると下記のような構造になっています。

 <xsd:complexType name="PurchaseOrderType">
  <xsd:sequence>
   <xsd:element name="ShipTo" type="tns:USAddress" maxOccurs="2"/>
   <xsd:element name="BillTo" type="tns:USAddress"/>
  </xsd:sequence>
  <xsd:attribute name="OrderDate" type="xsd:date"/>
 </xsd:complexType>

これはまさに「シーケンスに直接の子要素が2つ以上定義」されていて「maxoccurs 属性に1以外の値が指定されている」状態です。

従いまして、「例外的なデータ」になった理由はこの条件に該当した事によると推察致します。

またその後に2つのセル範囲に分けて対応付た時は、「子要素が2つ以上定義」されている状態から外れた事によりエクスポートできたと推察致します。

別のcompositor要素が直接の子要素として含まれている

「別のcompositor要素」にはchoice要素とall要素がありますが、まずはchoice要素から確認します。

choice要素を確認する

検証のために下記のように「シンプルなスキーマ」のShipTo要素とBillTo要素の間にchoice要素を追加します。

  <xsd:sequence>
   <xsd:element name="ShipTo" type="tns:USAddress" maxOccurs="2"/>
   <xsd:choice>
    <xsd:element name='comment1' type='xsd:string'/>
    <xsd:element name='comment2' type='xsd:string'/>
   </xsd:choice>
   <xsd:element name="BillTo" type="tns:USAddress"/>
  </xsd:sequence>

このスキーマファイルをmaxOccursが設定されているShipTo要素とそれ以外(追加したcomment要素を含む)の2つに分けて対応付けをして「エクスポートする対応付けの確認…」リンクをクリックすると、左図のように「エクスポートできない」というメッセージボックスが表示されます。

エラーの理由は「対応付けられた要素と他の要素のリレーションシップは保持されません」という、まさに最初の場合「対応付けられた要素とその他の要素との関係を維持できない場合にはエクスポートできません」に適合した内容です。

ただし、後段でご説明しますが実はchoice要素は「maxoccurs 属性に1以外の値が指定されている」とは関係なく単独で使用した場合でも上記のエラーになります。

all要素を確認する

実はall要素はchoice要素とは異なりShipTo要素とBillTo要素の間にall要素を追加すると構造解析の時点でエラーになります。

そうなると、all要素は「別のcompositor要素が直接の子要素として含まれている」という条件では対象外になります。

そうは言いながら念のために下記のように「シンプルなスキーマ」のShipTo要素とBillTo要素の間に一旦comment要素を作りその子要素としてall要素を追加した形で確認してみます。

  <xsd:sequence>
   <xsd:element name="ShipTo" type="tns:USAddress" maxOccurs="2"/>
   <xsd:element name="comment">
    <xsd:complexType>
     <xsd:all>
      <xsd:element name='comment1' type='xsd:string'/>
      <xsd:element name='comment2' type='xsd:string'/>
     </xsd:all>
    </xsd:complexType>
   </xsd:element>
   <xsd:element name="BillTo" type="tns:USAddress"/>
  </xsd:sequence>

このスキーマファイルをmaxOccursが設定されているShipTo要素とそれ以外(追加したall要素を含む)の2つに分けて対応付けをして「エクスポートする対応付けの確認…」リンクをクリックすると、左図のように「エクスポートできる」というメッセージボックスが表示されます。

この形では「all要素が直接の子要素として含まれている」訳ではないので、エラーにならないと推察されます。

以上の結果を踏まえると

「別のcompositor要素が直接の子要素として含まれている」という記述については、気しなくて良さそうです。

以上で「①対応付けられた要素とその他の要素との関係を維持できない場合」の一通りのご説明が完了しました。

②次のXMLスキーマ構造のいずれかが含まれているXMLの対応付けはエクスポートできません。

2つのパートに分けて構成されている「ブック内のXMLの対応付けをエクスポートできない」の後半に移ります。

記載されているXMLスキーマ構造は次の3つです。

  • リストのリスト 
  • 正規化されていないデータ
  • 選択肢

初見ではどのような事を意味しているのか解り難いので、ひとつひとつ見て行く事にします。

リストのリストとは?

続きの説明は「項目の一覧には、2つの項目のリストがあります」と書かれているのですが、具体的な構造は思い浮かばない事と存じます。

「リストのリスト」がどのような構造の時に出現するのか?を実際に探ってみると、「リスト」とは「maxOccursが1以外に設定されている要素」である事が解ります。

つまり「リストのリスト」とは「maxOccursが1以外に設定されている要素の子要素の中に、 maxOccursが1以外に設定されている子要素がある」事を意味しています。

この具体的な例につきましては、次にご説明する「1レコードではなく複数レコードになった場合」の中でご紹介いたします。

正規化されていないデータとは?

続きの説明を下記に引用します。

XMLテーブルの中に、1回だけ発生するように定義されている要素、つまり、maxoccurs属性が 1に設定されている要素が含まれています。
このような要素を XMLテーブルに追加すると、Excelはテーブルの列をこの要素の複数のインスタンスで埋め尽くします。

これもまた難解な言い回しですが、XMLテーブルとは「セルに対応付けした時に自動指定されるテーブル」であると考える事ができます。

対応付けした時にテーブルになるのは複数レコードが存在するmaxOccurs属性が1以外の要素がある場合です。

そのXMLテーブルにmaxoccurs属性が1に設定されている要素が対応付けられている場合は「正規化されないデータ」になると理解できます。

これは一番最初に「シンプルなスキーマ」のすべての項目をセルに対応付けるた時の状況と同じ状況になる認識です。

ただその時のエラーメッセージは「例外的なデータ」になっていました。

前章の①においては、上記は「シーケンスに直接の子要素が2つ以上定義」されていて「maxoccurs 属性に1以外の値が指定されている」状態に当たるとご説明しましたが、今回の「正規化されないデータ」にも当てはまると言えます。

そう考えると「例外的なデータ」のメッセージが何を意味しているのか?は、現時点では詳しく把握できていません。

将来的に解った事がありましたら内容を修正したいと思います。

選択肢とは?

続きの説明は「対応付けられた要素は、<choice>スキーマ構成の一部です」になります。

先の章でchoice要素をご説明しましたが、その時は「maxOccursが1以外に設定されている要素」とのand条件が必要だったのですが、これを見るとchoice要素があるだけでエラーになりそうな雰囲気です。

そこで試しに先ほど使用したchoice要素を追加した「シンプルなスキーマ」の中のmaxOccurs属性を1に修正し、すべての項目をセルに対応付けしたところ、左図のように対応付けしたセルは枠線表示になっています。

その上で「エクスボートする対応付けの確認」をすると先の章と同じ「対応付けられた要素と他の要素のリレーションシップは保持されません」のエラーメッセージが表示されます。

以上の結果から「choice要素が使用されているとExcelではエクスポートできない」と言えそうです。

以上で「XMLスキーマの構造によりエクスポートできない場合」の説明は終わりにいたします。

次にペンディングにしている1つのレコードではなく複数レコードになった場合の対応法について考えてみたいと思います。

「シンプルなスキーマ」を複数レコードに変更して確認する

1つのレコードの場合は対応付けするセル範囲を2つに分ける事でエクスポートできましたが、これが複数レコードになった場合にはどのような動きになるのでしょうか?

この確認をするために「シンプルなスキーマ」のルート要素である「PurchaseOrder」に対して、maxOccursをunboundedに設定した新たなルート要素「PurchaseOrders」を追加します。

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
           xmlns:tns="http://tempuri.org/PurchaseOrderSchema.xsd"
           targetNamespace="http://tempuri.org/PurchaseOrderSchema.xsd"
           elementFormDefault="qualified">

 <xsd:element name="PurchaseOrders" type="tns:PurchaseOrdersType"/>
 <xsd:complexType name="PurchaseOrdersType">
  <xsd:sequence>
   <xsd:element maxOccurs="unbounded" ref="tns:PurchaseOrder"/>
  </xsd:sequence>
 </xsd:complexType>

 <xsd:element name="PurchaseOrder" type="tns:PurchaseOrderType"/>
   … 以降は「シンプルなスキーマ」と同じ

maxOccursが1以外に設定されている「ShipTo要素」と「それ以外の要素」を2つのセル範囲に分けて対応付けしています。

ただし1レコードの時は枠線表示されていた「それ以外の要素」もmaxOccursはunboundedであるために複数レコードを表すテーブル表示に変わっています。

「エクスボートする対応付けの確認」をすると「複数リストのリスト」というエラーメッセージが表示されてエクスポートする事はできません。

これは先の章でご説明した「リストのリスト」の実例になります。

「リストのリスト」を解消する方法はあるのか?

残念ながらExcelに備わる機能を使って「リストのリスト」を解消する事は難しい認識です。

そうなるとスキーマファイルの構造に手を加えて対応するしか方法はありません。

例えばmaxOccursはunboundedの子要素がmaxOccursが2とか3である場合は、冗長化しますがmaxOccurs分の要素を名前付けして分ける事で、maxOccursそのものを無くしてしまう対応方法が考えられます。

ただしこのやり方を採用したとしても運用で回避しなければならない問題が残りますので、具体的に内容を見て行きたいと思います。

maxOccursの箇所を変更して対応する

複数レコードに対応させた「シンプルなスキーマ」でmaxOccursが2に設定されているShipTo要素をShipTo-1要素とShipTo-2要素の2要素に分けて、maxOccursを使わなくします。

 <xsd:element name="PurchaseOrder" type="tns:PurchaseOrderType"/>
 <xsd:complexType name="PurchaseOrderType">
  <xsd:sequence>
   <xsd:element name="ShipTo-1" type="tns:USAddress"/>
   <xsd:element name="ShipTo-2" type="tns:USAddress"/>
   <xsd:element name="BillTo" type="tns:USAddress"/>
  </xsd:sequence>
  <xsd:attribute name="OrderDate" type="xsd:date"/>
 </xsd:complexType>

これで「もしもShipTo-2要素だけセル範囲を別にして対応付けした状態でエクスポートできれば、ShipTo-2に空タグが入り込まないのではないか?」と想定したのですが…

実際に試してみるとルート要素の直接の子要素でmaxOccursが1以外に設定されていると、残念ながら「対応付けられた要素と他の要素のリレーションシップは保持されません」のエラーメッセージが表示されてエクスポートできない事が解ります。

これは要素の塊をもっと小さくして、対応付けするセル範囲の数を増やしたとしても、結果は同じになります。

どうやらこの場合はすべての項目を1つのセル範囲で対応付けるしかエクスポートできないようです。

なおルート要素の直接の子要素のmaxOccursが1以外に設定されている時は、先の章の①で見たように「直接の子要素が2つ以上定義されている」場合は「例外的なエラー」になります。

これは要素ではなく属性(attribute)であったとしても「例外的なエラー」になるので注意が必要です。

実際にサンプルXMLファイルを作ってエクスポートしてみる

少し長くはなりますが、下記左側が元のXMLファイルで、右側がエクスポートしたXMLファイルになります。

※下記は前段で使用したXMLファイルを複数レコードになるように修正したものです。
Micorosoftの米国のセールスオフィスの住所情報を使用していますが、内容は架空になります。

<?xml version="1.0" encoding="UTF-8"?>
<PurchaseOrders xmlns="http://tempuri.org/PurchaseOrderSchema.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <PurchaseOrder OrderDate="2021-09-20">
  <ShipTo-1 country="US">
   <name>Corporate Sales Office: Boise</name>
   <street>401 W. Front Street, Suite 600</street>
   <city>Boise</city>
   <state>ID</state>
   <zip>83702</zip>
  </ShipTo-1>
  <ShipTo-2 country="US">
   <name>Corporate Sales Office: San Francisco</name>
   <street>555 California, Suite 200</street>
   <city>San Francisco</city>
   <state>CA</state>
   <zip>94104</zip>
  </ShipTo-2>
  <BillTo country="US">
   <name>Corporate Sales Office: Sacramento</name>
   <street>1415 L Street, Suite 200</street>
   <city>Sacramento</city>
   <state>CA</state>
   <zip>95814</zip>
  </BillTo>
 </PurchaseOrder>
 <PurchaseOrder OrderDate="2021-09-22">
  <ShipTo-1 country="US">
   <name>Corporate Sales Office: Austin</name>
   <street>10900 Stonelake Boulevard, Suite 225</street>
   <city>Austin</city>
   <state>TX</state>
   <zip>78759</zip>
  </ShipTo-1>
  <BillTo country="US">
   <name>Corporate Sales Office: Tulsa</name>
   <street>7633 E. 63rd Place, Suite 300</street>
   <city>Tulsa</city>
   <state>OK</state>
   <zip>74133</zip>
  </BillTo>
 </PurchaseOrder>
</PurchaseOrders>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns1:PurchaseOrders xmlns:ns1="http://tempuri.org/PurchaseOrderSchema.xsd">
	<ns1:PurchaseOrder OrderDate="2021-09-20">
		<ns1:ShipTo-1 country="US">
			<ns1:name>Corporate Sales Office: Boise</ns1:name>
			<ns1:street>401 W. Front Street, Suite 600</ns1:street>
			<ns1:city>Boise</ns1:city>
			<ns1:state>ID</ns1:state>
			<ns1:zip>83702</ns1:zip>
		</ns1:ShipTo-1>
		<ns1:ShipTo-2 country="US">
			<ns1:name>Corporate Sales Office: San Francisco</ns1:name>
			<ns1:street>555 California, Suite 200</ns1:street>
			<ns1:city>San Francisco</ns1:city>
			<ns1:state>CA</ns1:state>
			<ns1:zip>94104</ns1:zip>
		</ns1:ShipTo-2>
		<ns1:BillTo country="US">
			<ns1:name>Corporate Sales Office: Sacramento</ns1:name>
			<ns1:street>1415 L Street, Suite 200</ns1:street>
			<ns1:city>Sacramento</ns1:city>
			<ns1:state>CA</ns1:state>
			<ns1:zip>95814</ns1:zip>
		</ns1:BillTo>
	</ns1:PurchaseOrder>
	<ns1:PurchaseOrder OrderDate="2021-09-22">
		<ns1:ShipTo-1 country="US">
			<ns1:name>Corporate Sales Office: Austin</ns1:name>
			<ns1:street>10900 Stonelake Boulevard, Suite 225</ns1:street>
			<ns1:city>Austin</ns1:city>
			<ns1:state>TX</ns1:state>
			<ns1:zip>78759</ns1:zip>
		</ns1:ShipTo-1>
		<ns1:ShipTo-2>
			<ns1:name/>
			<ns1:street/>
			<ns1:city/>
			<ns1:state/>
			<ns1:zip/>
		</ns1:ShipTo-2>
		<ns1:BillTo country="US">
			<ns1:name>Corporate Sales Office: Tulsa</ns1:name>
			<ns1:street>7633 E. 63rd Place, Suite 300</ns1:street>
			<ns1:city>Tulsa</ns1:city>
			<ns1:state>OK</ns1:state>
			<ns1:zip>74133</ns1:zip>
		</ns1:BillTo>
	</ns1:PurchaseOrder>
</ns1:PurchaseOrders>

左側のPurchaseOrderの2レコードはShipTo-2要素はデータがありませんが、右側のエクスポートした場合は、空タグでShipTo-2要素が出力されています。

実運用でExcelでのエクスポートをデザインする場合は、このようなデータの冗長化に対する対応策、例えば空タグを取り除くスクリプト作成など、を事前に検討して置く必要がありそうです。

ただし空タグが残っていてもエクスポートしたXMLファイルをExcelに読み込む事はできますが…

まとめ

「スキーマファイル(*.xsd)がどのような構造であればエクスポートできるか?」について見てきました。

読み込み(インポート)の第2回でご説明致しましたが、下記の要素・属性・構造は読み込む事ができず、つまり読み込めないという事はエクスポートできないと同じ意味になる認識です。

  • <any>
  • <anyAttribute>
  • <substitutionGroup>
  • 再帰構造—Recursive structures
  • 抽象要素—Abstract elements
  • 混在したコンテンツ—Mixed content

これに加えて、今回ご説明したように下記の要素・属性はエクスポートできない事になります。

  • <choice>
  • <maxOccurs>が1以外の値に設定されている

この中でもmaxOccursは、付随する条件はありますが、「リストのリスト」の構造を含めて「ほぼほぼエクスポートする事ができない」大きな要因になっている認識です。

そうなるとExcelでXMLファイルをエクスポートしなければならない時は、事前にスキーマファイルを作る段階でmaxOccursに対する対処法を施して置く必要がありそうです。

次回はMicrosoft Docsに掲載されている「購買発注書のスキーマ」を使ってmaxOccursがunboundedの場合の対応方法について検討して見たいと思います。

以上最後までご一読いただき誠にありがとうございました。