

# AWS Glue で XML 形式を使用する
<a name="aws-glue-programming-etl-format-xml-home"></a>

AWS Glue はソースからデータを取得し、さまざまなデータ形式で保存および転送されたターゲットにデータを書き込みます。このドキュメントでは、データが XML データ形式で保存または転送される場合に、AWS Glue でデータを使用する際に利用できる機能について説明します。

AWS Glue は XML 形式の使用をサポートしています。この形式は、行ベースでも列ベースでもない、非常に設定可能性が高く、厳密に定義されたデータ構造を表します。XML は高度に標準化されています。標準局から発行されている形式の概要については、「[XML エッセンシャル](https://www.w3.org/standards/xml/core)」を参照してください。

AWS Glue を使用して、Amazon S3 から XML ファイルを読み込んだり、XML ファイルが含まれる `bzip` および `gzip` アーカイブを読み込んだりすることができます。このページで説明する設定ではなく、[S3 接続パラメータ](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3) 上で圧縮動作を設定します。

次の表は、XML 形式オプションをサポートする一般的な AWS Glue 機能を示しています。


| 読み込み | 書き込み | ストリーミングの読み取り | 小さなファイルのグループ化 | ジョブのブックマーク | 
| --- | --- | --- | --- | --- | 
| サポート | サポートされていません | サポートされていません | サポート | サポート | 

## 例: S3 から XML を読み込む
<a name="aws-glue-programming-etl-format-xml-read"></a>

 XML リーダーは XML タグ名を取得します。入力内にあるそのタグを持つ要素を調べてスキーマを推測し、対応する値を DynamicFrame に入力します。AWS Glue XML の機能は、[Apache Spark の XML データソース](https://github.com/databricks/spark-xml)に類似した動作をします。このリーダーをそのプロジェクトのドキュメントと比較することで、基本的な動作に関する洞察が得られる可能性があります。

**前提条件:** 読み取りたい XML ファイルまたはフォルダへの S3 パス (`s3path`) と、XML ファイルに関するいくつかの情報が必要です。また、読み込みたい XML 要素のタグである `xmlTag` が必要です。

 **設定:** 関数オプションで `format="xml"` を指定します。`connection_options` で、`paths` キーを使用して `s3path` を指定します。リーダーが S3 とやり取りする方法は、`connection_options` でさらに詳しく設定できます。詳細については、AWS Glue: [S3 接続パラメータ](aws-glue-programming-etl-connect-s3-home.md#aws-glue-programming-etl-connect-s3) の「ETL の接続タイプとオプション」を参照してください。`format_options` で、`rowTag` キーを使用して `xmlTag` を指定します。リーダーが XML ファイルを解釈する方法は、`format_options` でさらに詳しく設定できます。詳細については、「[XML 設定リファレンス](#aws-glue-programming-etl-format-xml-reference)」を参照してください。

次の AWS Glue ETL スクリプトは、S3 から XML ファイルまたはフォルダを読み取るプロセスを示しています。

------
#### [ Python ]

この例では [create\$1dynamic\$1frame.from\$1options](aws-glue-api-crawler-pyspark-extensions-glue-context.md#aws-glue-api-crawler-pyspark-extensions-glue-context-create_dynamic_frame_from_options) メソッドを使用します。

```
# Example: Read XML from S3
# Set the rowTag option to configure the reader.

from awsglue.context import GlueContext
from pyspark.context import SparkContext

sc = SparkContext.getOrCreate()
glueContext = GlueContext(sc)

dynamicFrame = glueContext.create_dynamic_frame.from_options(
    connection_type="s3",
    connection_options={"paths": ["s3://s3path"]},
    format="xml",
    format_options={"rowTag": "xmlTag"},
)
```

スクリプト (`pyspark.sql.DataFrame`) では DataFrame を使用することもできます。

```
dataFrame = spark.read\
    .format("xml")\
    .option("rowTag", "xmlTag")\
    .load("s3://s3path")
```

------
#### [ Scala ]

この例では [getSourceWithFormat](glue-etl-scala-apis-glue-gluecontext.md#glue-etl-scala-apis-glue-gluecontext-defs-getSourceWithFormat) 操作を使用します。

```
// Example: Read XML from S3
// Set the rowTag option to configure the reader.

import com.amazonaws.services.glue.util.JsonOptions
import com.amazonaws.services.glue.GlueContext
import org.apache.spark.sql.SparkSession

val glueContext = new GlueContext(SparkContext.getOrCreate())
val sparkSession: SparkSession = glueContext.getSparkSession

object GlueApp {
  def main(sysArgs: Array[String]): Unit = {
    val dynamicFrame = glueContext.getSourceWithFormat(
      formatOptions=JsonOptions("""{"rowTag": "xmlTag"}"""), 
      connectionType="s3", 
      format="xml", 
      options=JsonOptions("""{"paths": ["s3://s3path"], "recurse": true}""")
    ).getDynamicFrame()
}
```

スクリプト (`org.apache.spark.sql.DataFrame`) では DataFrame を使用することもできます。

```
val dataFrame = spark.read
  .option("rowTag", "xmlTag")
  .format("xml")
  .load("s3://s3path“)
```

------

## XML 設定リファレンス
<a name="aws-glue-programming-etl-format-xml-reference"></a>

AWS Glue ライブラリが `format="xml"` を指定している場合には、以下の `format_options` を使用することができます。
+ `rowTag` - 行として扱うファイル内の XML タグを指定します。行のタグを自己終了型にすることはできません。
  + **タイプ:** テキスト、**必須**
+ `encoding` - 文字エンコードを指定します。これは、ランタイム環境がサポートする [Charset](https://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html) の名前またはエイリアスにすることができます。エンコーディングのサポートに関しては特に保証していませんが、主要なエンコーディングは動作するはずです。
  + **タイプ:** テキスト、**デフォルト:** `"UTF-8"`
+ `excludeAttribute` - 要素の属性を除外するかどうかを指定します。
  + **タイプ:** ブール値、**デフォルト:** `false`
+ `treatEmptyValuesAsNulls` - 空白文字を null 値として扱うかどうかをします。
  + **タイプ:** ブール値、**デフォルト:** `false`
+ `attributePrefix` - 子要素テキストから区別するために属性に付加するプレフィックス。このプレフィックスをフィールド名として使用します。
  + **タイプ:** テキスト、**デフォルト:** `"_"`
+ `valueTag` - 要素内に子を持たない属性がある場合、値に使用するタグ。
  + **タイプ:** テキスト、**デフォルト:** `"_VALUE"`
+ `ignoreSurroundingSpaces` - 値を囲む空白文字を無視するかどうかを指定します。
  + **タイプ:** ブール値、**デフォルト:** `false`
+ `withSchema` - 推論されたスキーマを上書きしたい場合に、期待されるスキーマを含みます。このオプションを使用しない場合は、AWS Glue で XML データからスキーマを推定します。
  + **タイプ:** テキスト、**デフォルト:** 該当なし
  + 値は `StructType` を表す JSON オブジェクトである必要があります。

## XML スキーマを手動で指定する
<a name="aws-glue-programming-etl-format-xml-withschema"></a>

**手動 XML スキーマの例**

これは、XML データ用にスキーマを指定するために、`withSchema` 形式オプションを使用する場合の例です。

```
from awsglue.gluetypes import *

schema = StructType([ 
  Field("id", IntegerType()),
  Field("name", StringType()),
  Field("nested", StructType([
    Field("x", IntegerType()),
    Field("y", StringType()),
    Field("z", ChoiceType([IntegerType(), StringType()]))
  ]))
])

datasource0 = create_dynamic_frame_from_options(
    connection_type, 
    connection_options={"paths": ["s3://xml_bucket/someprefix"]},
    format="xml", 
    format_options={"withSchema": json.dumps(schema.jsonValue())},
    transformation_ctx = ""
)
```