例
次の例では、Velocityトランスフォーメーションを使用して、XMLデータの形式を別の形式に変換したり、JSONデータを変換して拡張したりする方法を示します。
XML変換の例
XMLファイル内に製品データがあり、別の形式のXMLに変換する必要があります。
変換するXMLファイルのproducts.xmlには、次の形式のデータが含まれています。
<?xml version="1.0" encoding="UTF-8"?>
<document>
<product>
<id>1</id>
<name>milk</name>
<size>16 oz</size>
</product>
<product>
<id>2</id>
<name>water</name>
<size> 8 oz</size>
</product>
</document>
XMLを変換して、各製品が独自の要素内に含まれるようにする必要があります(<milk>...</milk>など)。また、XMLファイル内のコメントにタイムスタンプを追加する必要があります。
ファイルを変換するには、まず、変換するXMLファイルのパスを含むソースファイルを作成して、マッピングがXMLファイルからデータを読み取れるようにします。その後、マッピングを作成します。
次の行を含む「filepath.txt」という名前のテキストファイルを作成します。
C:\XMLSources\products.xml
ソースファイルを作成したら、マッピングを作成します。次の図に、マッピングを示します。
次の方法でトランスフォーメーションを構成します。
- ソーストランスフォーメーション
ファイルパスを含むファイルからデータを読み取るようにソーストランスフォーメーションを設定し、ソース形式オプションを設定します。
[ソース]タブで、ソースファイルにアクセスできる接続を選択し、ソースタイプを[単一オブジェクト]に設定して、ソースオブジェクトとしてfilepath.txtを選択します。
[形式オプション]をクリックして、次のプロパティを設定します。
プロパティ | 値 |
---|
フラットファイルタイプ | 区切り |
引用符 | なし |
フィールドラベル | 自動生成 |
最初のデータ行 | 1 |
- Velocityトランスフォーメーション
Velocityトランスフォーメーションの入力を設定し、テンプレートを作成します。
[入力形式]タブで、次のプロパティを設定します。
プロパティ | 値 |
---|
入力フィールド | ソーストランスフォーメーションからの受信文字列フィールド。 |
入力タイプ | ファイル |
入力形式 | XML |
テンプレートの変数名 | ルート |
コードページ | UTF-8 |
[Velocityテンプレート]タブで、テンプレートエディタに次のテンプレートを入力し、構文を検証します。
<?xml version="1.0" encoding="UTF-8"?>
<!--Generation date: $function.call('Systimestamp')-->
## Convert each product to an element:
<products>
#foreach ($child in $root.getRootElement().getChildren() )
<$child.getChild("name").getText()>
<id>$child.getChild("id").getText()</id>
<size>$child.getChild("size").getText()</size>
</$child.getChild("name").getText()>
#end
</products>
- ターゲットトランスフォーメーション
実行時に作成されるフラットファイルターゲットにデータを書き込むように、ターゲットトランスフォーメーションを設定します。ターゲットファイルにヘッダーとテキスト修飾子文字が含まれないようにするために、形式オプションを設定します。
[ターゲット]タブで、接続を選択し、ターゲットタイプを[単一オブジェクト]に設定します。[オブジェクト]フィールドの横にある[選択]をクリックします。[実行時に新規作成]を選択して、ファイル名に「products_converted.xml」と入力します。
[形式オプション]をクリックして、テキスト修飾子を[なし]に設定します。
詳細プロパティで、ヘッダーオプションを[ヘッダーなし]に設定します。
マッピングを実行すると、ターゲットファイルのproducts_converted.xmlには次のXMLが含まれます。
<?xml version="1.0" encoding="UTF-8"?>
<!--Generation date: 06/17/2020 17:45:41.341526-->
<products>
<milk>
<id>1</id>
<size>16 oz</size>
</milk>
<water>
<id>2</id>
<size> 8 oz</size>
</water>
</products>
JSON変換の例
データベースのJSON BLOBに保存されているオンラインレビューサービスからのベンダデータがあります。レコードをフィルタし、データを別の形式に変換して、JSONファイルに書き込む必要があります。また、追加の属性でデータを拡張する必要があります。
データベースには、次の形式のデータを含むJSON BLOBが含まれています。
{"items":[
{"business_id":"1SWheh84yJXfytovILXOAQ","name":"Rancho Golf Club","address":"1200 E Camino Acequia Drive","postal_code":"85016","stars":3.0,"review_count":5,"is_open":0,"attributes":{"GoodForKids":"False"},"categories":"Golf, Active Life","hours":null},
{"business_id":"QXAEGFB4oINsVuTFxEYKFQ","name":"Garden Blessing Chinese Restaurant","address":"25 Eglinton Avenue W","postal_code":"L5R 3E7","stars":2.5,"review_count":128,"is_open":1,"attributes":{"RestaurantsReservations":"True","GoodForMeal":"{'dessert': False, 'latenight': False, 'lunch': True, 'dinner': True, 'brunch': False, 'breakfast': False}","BusinessParking":"{'garage': False, 'street': False, 'validated': False, 'lot': True, 'valet': False}","Caters":"True","NoiseLevel":"u'loud'","RestaurantsTableService":"True","RestaurantsTakeOut":"True","RestaurantsPriceRange2":"2","OutdoorSeating":"False","BikeParking":"False","Ambience":"{'romantic': False, 'intimate': False, 'classy': False, 'hipster': False, 'divey': False, 'touristy': False, 'trendy': False, 'upscale': False, 'casual': True}","HasTV":"False","WiFi":"u'no'","GoodForKids":"True","Alcohol":"u'full_bar'","RestaurantsAttire":"u'casual'","RestaurantsGoodForGroups":"True","RestaurantsDelivery":"False"},"categories":"Specialty Food, Restaurants, Dim Sum, Imported Food, Food, Chinese, Ethnic Food, Seafood","hours":{"Monday":"9:0-0:0","Tuesday":"9:0-0:0","Wednesday":"9:0-0:0","Thursday":"9:0-0:0","Friday":"9:0-1:0","Saturday":"9:0-1:0","Sunday":"9:0-0:0"}},
{"business_id":"gnKjwL_1w79qoiV3IC_xQQ","name":"Fujiyama Japanese Cuisine","address":"111 Johnston Rd, Ste 15","postal_code":"28210","stars":4.0,"review_count":170,"is_open":1,"attributes":{"GoodForKids":"True","NoiseLevel":"u'average'","RestaurantsDelivery":"False","GoodForMeal":"{'dessert': False, 'latenight': False, 'lunch': True, 'dinner': True, 'brunch': False, 'breakfast': False}","Alcohol":"u'beer_and_wine'","Caters":"False","WiFi":"u'no'","RestaurantsTakeOut":"True","BusinessAcceptsCreditCards":"True","Ambience":"{'romantic': False, 'intimate': False, 'touristy': False, 'hipster': False, 'divey': False, 'classy': False, 'trendy': False, 'upscale': False, 'casual': True}","BusinessParking":"{'garage': False, 'street': False, 'validated': False, 'lot': True, 'valet': False}","RestaurantsTableService":"True","RestaurantsGoodForGroups":"True","OutdoorSeating":"False","HasTV":"True","BikeParking":"True","RestaurantsReservations":"True","RestaurantsPriceRange2":"2","RestaurantsAttire":"'casual'"},"categories":"Sushi Bars, Restaurants, Japanese","hours":{"Monday":"17:30-21:30","Wednesday":"17:30-21:30","Thursday":"17:30-21:30","Friday":"17:30-22:0","Saturday":"17:30-22:0","Sunday":"17:30-21:0"}}
...
レコードをフィルタして、星が3つ以上のレストランのみが含まれるようにする必要があります。また、郵便番号に基づいて各レコードに市区町村を追加する必要があります。
郵便番号と対応する市区町村は、次の形式でフラットファイル内にあります。
postal_code|city
15090|Wexford, PA
15102|Bethel Park, PA
15206|Pittsburgh, PA
15317|Canonsburg, PA
28012|Belmont, NC
28027|Concord, NC
...
ターゲットファイルに次の形式でJSONデータを含める必要があります。
{ "Date": "<date>",
"vendors":[
{
"name": "<restaurant name>",
"location": "<city, state/province>",
"desc": "<description>",
"stars": <number of stars>
}
,
...
データを変換するには、JSONデータを変換するVelocityトランスフォーメーションと、郵便番号に基づいて市区町村を返す接続されていないルックアップトランスフォーメーションを使用してマッピングを作成します。
次の図に、マッピングを示します。
次の方法でトランスフォーメーションを構成します。
- ソーストランスフォーメーション
- JSON BLOBを含むデータベーステーブルからデータを読み取るように、ソーストランスフォーメーションを設定します。
- Velocityトランスフォーメーション
Velocityトランスフォーメーションの入力を設定し、テンプレートを作成します。
[入力形式]タブで、次のプロパティを設定します。
プロパティ | 値 |
---|
入力フィールド | JSON BLOBを含むソーストランスフォーメーションからの受信文字列フィールド。 |
入力タイプ | バッファ |
入力形式 | JSON |
テンプレートの変数名 | inputRoot |
コードページ | デフォルト |
[Velocityテンプレート]タブで、テンプレートエディタに次のテンプレートを入力し、構文を検証します。
#set($comma ="")
{ "Date": "$function.call('Systimestamp')",
"vendors":[
#foreach($vend in $inputRoot.items)
#if($vend.categories.toString().contains("Restaurants") && ($vend.stars > 3))$comma
{
"name": "$vend.name",
"location": "$function.call(':lkp.lkp_CityLookup', $vend.postal_code)",
"desc": "$vend.categories",
"stars": $vend.stars
}
#set($comma =",")
#end
#end
]
}
- 接続されていないルックアップトランスフォーメーション
郵便番号に基づいて市区町村を返すように、ルックアップトランスフォーメーションを設定します。ルックアップトランスフォーメーションは、Velocityトランスフォーメーションのテンプレートから呼び出すことができるように、接続されていないルックアップトランスフォーメーションである必要があります。
[全般]タブで、[接続されていないルックアップ]を選択します。
[受信フィールド]タブで、in_postal_codeという名前の郵便番号用の受信フィールドを作成します。
[ルックアップオブジェクト]タブで、郵便番号と市区町村を含むテキストファイルを選択します。次に、[形式オプション]をクリックして、次のプロパティを設定します。
プロパティ | 値 |
---|
フラットファイルタイプ | 区切り |
区切り文字 | その他: | |
引用符 | なし |
フィールドラベル | 行1からインポート |
最初のデータ行 | 2 |
[ルックアップ条件]タブで、次のルックアップ条件を設定します。
postal_code = in_postal_code
[戻りフィールド]タブで、戻りフィールドとしてcityを選択します。
- ターゲットトランスフォーメーション
実行時に作成されるフラットファイルターゲットにデータを書き込むように、ターゲットトランスフォーメーションを設定します。ターゲットファイルにヘッダーとテキスト修飾子文字が含まれないようにするために、形式オプションを設定します。
[ターゲット]タブで、接続を選択し、ターゲットタイプを[単一オブジェクト]に設定します。[オブジェクト]フィールドの横にある[選択]をクリックします。[実行時に新規作成]を選択して、ファイル名に「vendors.json」と入力します。
[形式オプション]をクリックして、テキスト修飾子を[なし]に設定します。
詳細プロパティで、ヘッダーオプションを[ヘッダーなし]に設定します。
マッピングを実行すると、ターゲットファイルのvendors.jsonには次のデータが含まれます。
{ "Date": "07/08/2020 12:33:44.647037",
"vendors":[
{
"name": "Fujiyama Japanese Cuisine",
"location": "Charlotte, NC",
"desc": "Sushi Bars, Restaurants, Japanese",
"stars": 4.0
}
,
{
"name": "D'Amico's Pizzeria",
"location": "Mentor-on-the-Lake, OH",
"desc": "Italian, Restaurants, Pizza, Chicken Wings",
"stars": 4.0
}
,
{
"name": "Villa Borghese",
"location": "Las Vegas, NV",
"desc": "Restaurants, Italian",
"stars": 4.0
}
,
{
"name": "3-Rivers Diner",
"location": "Pittsburgh, PA",
"desc": "Sandwiches, Salad, Restaurants, Burgers, Comfort Food",
"stars": 4.0
}
,
...