「XMLで複数の商品やデータを表したいんだけど、どう書けばいいの?」
「同じタグを繰り返し書くのは正しいの?」
「配列やリストのようなデータをXMLで表現するには?」
こんな疑問を持つ方は多いでしょう。
XMLは階層構造でデータを表現しますが、同じ要素(タグ)を繰り返して書くことで、複数のデータをまとめて扱えます。
これは他のプログラミング言語でいう「配列」や「リスト」のような概念です。
この記事では、XMLの繰り返し要素について、基本的な概念から実際の書き方、よくある間違いと対策まで、初心者向けにわかりやすく解説します。
XMLの繰り返し要素とは?

基本的な概念
XMLでは同じタグを複数並べることで、繰り返しのデータを表現します。
これは次のような場面で使われます:
- 商品一覧
- ユーザーリスト
- 注文履歴
- 設定項目の集合
基本的な構造
<親要素>
<繰り返し要素>データ1</繰り返し要素>
<繰り返し要素>データ2</繰り返し要素>
<繰り返し要素>データ3</繰り返し要素>
</親要素>
具体例:注文データ
<order>
<item>
<name>ペン</name>
<price>100</price>
</item>
<item>
<name>ノート</name>
<price>200</price>
</item>
<item>
<name>消しゴム</name>
<price>50</price>
</item>
</order>
この例では:
<order>
:親要素(注文全体)<item>
:繰り返し要素(個別の商品)- 同じ構造の
<item>
が3つ並んでいる
他の言語との比較
JavaScript の配列
const items = [
{ name: "ペン", price: 100 },
{ name: "ノート", price: 200 },
{ name: "消しゴム", price: 50 }
];
Python のリスト
items = [
{"name": "ペン", "price": 100},
{"name": "ノート", "price": 200},
{"name": "消しゴム", "price": 50}
]
XMLの繰り返し要素は、これらの配列やリストと同じような役割を果たします。
繰り返し要素の実例

例1:顧客リスト
<customers>
<customer id="001">
<name>田中太郎</name>
<email>tanaka@example.com</email>
<phone>090-1234-5678</phone>
</customer>
<customer id="002">
<name>佐藤花子</name>
<email>sato@example.com</email>
<phone>090-2345-6789</phone>
</customer>
<customer id="003">
<name>鈴木一郎</name>
<email>suzuki@example.com</email>
<phone>090-3456-7890</phone>
</customer>
</customers>
例2:ブログの記事一覧
<blog>
<article id="001" published="2025-07-01">
<title>XMLの基本を学ぼう</title>
<author>山田太郎</author>
<content>XMLは構造化されたデータを表現するための...</content>
<tags>
<tag>XML</tag>
<tag>プログラミング</tag>
<tag>初心者向け</tag>
</tags>
</article>
<article id="002" published="2025-07-02">
<title>HTMLとXMLの違い</title>
<author>佐藤花子</author>
<content>HTMLとXMLは似ているようで...</content>
<tags>
<tag>HTML</tag>
<tag>XML</tag>
<tag>Webデザイン</tag>
</tags>
</article>
</blog>
例3:商品カタログ
<catalog>
<categories>
<category id="electronics" name="電子機器">
<products>
<product sku="EL001" featured="true">
<name>スマートフォン</name>
<price currency="JPY">89800</price>
<description>最新のプロセッサを搭載</description>
<specifications>
<spec name="画面サイズ">6.1インチ</spec>
<spec name="メモリ">8GB</spec>
<spec name="ストレージ">128GB</spec>
</specifications>
</product>
<product sku="EL002" featured="false">
<name>ワイヤレスイヤホン</name>
<price currency="JPY">15800</price>
<description>ノイズキャンセリング機能付き</description>
<specifications>
<spec name="バッテリー持続時間">8時間</spec>
<spec name="重量">45g</spec>
<spec name="防水性能">IPX4</spec>
</specifications>
</product>
</products>
</category>
<category id="books" name="書籍">
<products>
<product sku="BK001" featured="true">
<name>XMLプログラミング入門</name>
<price currency="JPY">2800</price>
<description>XMLの基礎から応用まで</description>
<specifications>
<spec name="ページ数">350ページ</spec>
<spec name="発行年">2025年</spec>
<spec name="言語">日本語</spec>
</specifications>
</product>
</products>
</category>
</categories>
</catalog>
繰り返し要素のメリット

データのまとまりがわかりやすい
繰り返し要素を使うと、どのデータがどの親に属するのか一目瞭然です。
良い例:構造が明確
<school>
<classes>
<class grade="3" section="A">
<students>
<student id="001">田中太郎</student>
<student id="002">佐藤花子</student>
</students>
</class>
<class grade="3" section="B">
<students>
<student id="003">鈴木一郎</student>
<student id="004">山田二郎</student>
</students>
</class>
</classes>
</school>
悪い例:構造が不明確
<school>
<student1-grade>3</student1-grade>
<student1-section>A</student1-section>
<student1-name>田中太郎</student1-name>
<student2-grade>3</student2-grade>
<student2-section>A</student2-section>
<student2-name>佐藤花子</student2-name>
</school>
プログラムで処理しやすい
プログラムでXMLを読み込むときは、繰り返し要素をループ処理で簡単に扱えます。
JavaScript での処理例
// XMLを解析
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlText, "text/xml");
// 繰り返し要素を取得してループ処理
const items = xmlDoc.getElementsByTagName("item");
for (let i = 0; i < items.length; i++) {
const name = items[i].getElementsByTagName("name")[0].textContent;
const price = items[i].getElementsByTagName("price")[0].textContent;
console.log(`商品: ${name}, 価格: ${price}円`);
}
Python での処理例
import xml.etree.ElementTree as ET
# XMLを解析
tree = ET.parse('products.xml')
root = tree.getroot()
# 繰り返し要素をループ処理
for item in root.findall('item'):
name = item.find('name').text
price = item.find('price').text
print(f"商品: {name}, 価格: {price}円")
データの追加・削除が簡単
新しいデータを追加する場合、同じ構造の要素を追加するだけです。
データ追加の例
<!-- 元のデータ -->
<products>
<product id="P001">
<name>商品A</name>
<price>1000</price>
</product>
<product id="P002">
<name>商品B</name>
<price>2000</price>
</product>
</products>
<!-- 新しい商品を追加 -->
<products>
<product id="P001">
<name>商品A</name>
<price>1000</price>
</product>
<product id="P002">
<name>商品B</name>
<price>2000</price>
</product>
<product id="P003">
<name>商品C</name>
<price>1500</price>
</product>
</products>
よくある間違いと注意点
間違い1:タグの閉じ忘れ
同じタグが何度も出てくると、どこを閉じたか混乱しがちです。
間違った例
<order>
<item>
<name>ペン</name>
<price>100</price>
<!-- </item> の閉じ忘れ -->
<item>
<name>ノート</name>
<price>200</price>
</item>
</order>
正しい例
<order>
<item>
<name>ペン</name>
<price>100</price>
</item> <!-- 必ず閉じる -->
<item>
<name>ノート</name>
<price>200</price>
</item> <!-- 必ず閉じる -->
</order>
対策
- インデントを揃える:階層がわかりやすくなる
- エディタの支援機能を使う:対応するタグをハイライト
- 一つずつ書いて確認:まとめて書かずに段階的に作成
間違い2:意味のない繰り返し
繰り返すのは「同じ意味のデータ」が複数ある場合に限ります。
間違った例
<person>
<data>田中</data>
<data>30</data>
<data>男性</data>
<data>東京都</data>
</person>
この例では、名前、年齢、性別、住所が全て<data>
になっていて、何を表しているかわかりません。
正しい例
<person>
<name>田中</name>
<age>30</age>
<gender>男性</gender>
<address>東京都</address>
</person>
または、本当に繰り返しが必要な場合:
<person>
<name>田中太郎</name>
<hobbies>
<hobby>読書</hobby>
<hobby>映画鑑賞</hobby>
<hobby>プログラミング</hobby>
</hobbies>
</person>
間違い3:ネストの混乱
深い階層の繰り返し要素で、どのタグがどこに属するかわからなくなる場合があります。
混乱しやすい例
<company>
<department><name>営業部</name><employees><employee><name>田中</name></employee><employee><name>佐藤</name></employee></employees></department><department><name>開発部</name><employees><employee><name>鈴木</name></employee></employees></department>
</company>
読みやすく整理した例
<company>
<departments>
<department id="sales">
<name>営業部</name>
<employees>
<employee id="001">
<name>田中太郎</name>
<position>営業マネージャー</position>
</employee>
<employee id="002">
<name>佐藤花子</name>
<position>営業担当</position>
</employee>
</employees>
</department>
<department id="development">
<name>開発部</name>
<employees>
<employee id="003">
<name>鈴木一郎</name>
<position>シニアエンジニア</position>
</employee>
</employees>
</department>
</departments>
</company>
XMLスキーマ(XSD)での繰り返し要素定義

基本的な繰り返し定義
XMLスキーマ(XSD)を使うと、「このタグは何回繰り返して良い」というルールを設定できます。
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="order">
<xs:complexType>
<xs:sequence>
<xs:element name="customer" type="xs:string"/>
<xs:element name="items">
<xs:complexType>
<xs:sequence>
<!-- itemを0回以上無制限に繰り返し可能 -->
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
繰り返し回数の制御
属性 | 意味 | 例 |
---|---|---|
minOccurs="0" | 0回以上(省略可能) | <xs:element name="note" minOccurs="0"/> |
maxOccurs="unbounded" | 無制限に繰り返し可能 | <xs:element name="item" maxOccurs="unbounded"/> |
minOccurs="1" maxOccurs="5" | 1回以上5回以下 | <xs:element name="photo" minOccurs="1" maxOccurs="5"/> |
実践的な例
<xs:element name="blog">
<xs:complexType>
<xs:sequence>
<!-- 記事は1つ以上必須 -->
<xs:element name="article" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="content" type="xs:string"/>
<!-- タグは0個以上5個以下 -->
<xs:element name="tag" type="xs:string" minOccurs="0" maxOccurs="5"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
実践的な設計パターン
パターン1:親要素で意味をまとめる
<library>
<!-- 書籍セクション -->
<books>
<book id="B001">
<title>XML入門</title>
<author>山田太郎</author>
</book>
<book id="B002">
<title>プログラミング基礎</title>
<author>佐藤花子</author>
</book>
</books>
<!-- 会員セクション -->
<members>
<member id="M001">
<name>田中一郎</name>
<membership-type>premium</membership-type>
</member>
<member id="M002">
<name>鈴木二郎</name>
<membership-type>basic</membership-type>
</member>
</members>
</library>
パターン2:複数階層の繰り返し
<university>
<faculties>
<faculty name="工学部">
<departments>
<department name="情報工学科">
<courses>
<course code="CS101">
<title>プログラミング入門</title>
<credits>2</credits>
<students>
<student id="S001">田中太郎</student>
<student id="S002">佐藤花子</student>
</students>
</course>
<course code="CS102">
<title>データ構造</title>
<credits>3</credits>
<students>
<student id="S001">田中太郎</student>
<student id="S003">鈴木一郎</student>
</students>
</course>
</courses>
</department>
</departments>
</faculty>
</faculties>
</university>
パターン3:設定ファイルでの繰り返し
<application-config>
<servers>
<server name="web-server-1" type="web">
<host>192.168.1.10</host>
<port>80</port>
<status>active</status>
</server>
<server name="db-server-1" type="database">
<host>192.168.1.20</host>
<port>3306</port>
<status>active</status>
</server>
<server name="cache-server-1" type="cache">
<host>192.168.1.30</host>
<port>6379</port>
<status>maintenance</status>
</server>
</servers>
<features>
<feature name="user-registration" enabled="true"/>
<feature name="email-notifications" enabled="false"/>
<feature name="advanced-search" enabled="true"/>
</features>
</application-config>
XPathを使った繰り返し要素の操作

基本的なXPath
<products>
<product id="P001" category="electronics">
<name>スマートフォン</name>
<price>89800</price>
</product>
<product id="P002" category="books">
<name>XML入門書</name>
<price>2800</price>
</product>
<product id="P003" category="electronics">
<name>タブレット</name>
<price>45800</price>
</product>
</products>
XPathの例
XPath | 説明 | 結果 |
---|---|---|
//product | 全ての product 要素 | 3つの商品全て |
//product[@category='electronics'] | 電子機器カテゴリの商品 | スマートフォンとタブレット |
//product[price > 30000] | 価格が30000より大きい商品 | スマートフォンとタブレット |
//product[1] | 最初の商品 | スマートフォン |
//product[last()] | 最後の商品 | タブレット |
JavaScript でのXPath使用例
// XMLドキュメントを取得
const xmlDoc = /* XMLDocument */;
// XPathで繰り返し要素を検索
const products = xmlDoc.evaluate(
"//product[@category='electronics']",
xmlDoc,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
);
// 結果をループ処理
for (let i = 0; i < products.snapshotLength; i++) {
const product = products.snapshotItem(i);
const name = product.getElementsByTagName("name")[0].textContent;
const price = product.getElementsByTagName("price")[0].textContent;
console.log(`${name}: ${price}円`);
}
パフォーマンスの考慮事項
大量データの処理
繰り返し要素が大量にある場合のパフォーマンス対策:
1. ストリーミング処理
import xml.etree.ElementTree as ET
# 大きなXMLファイルをストリーミング処理
def process_large_xml(file_path):
context = ET.iterparse(file_path, events=('start', 'end'))
context = iter(context)
event, root = next(context)
for event, elem in context:
if event == 'end' and elem.tag == 'product':
# 商品要素を処理
process_product(elem)
# メモリ節約のため要素をクリア
root.clear()
def process_product(product_elem):
name = product_elem.find('name').text
price = product_elem.find('price').text
print(f"処理中: {name} - {price}円")
2. インデックスの活用
<!-- 検索しやすくするため、重要な属性をインデックスとして使用 -->
<products>
<product id="P001" sku="PHONE-001" category="electronics">
<name>スマートフォン</name>
</product>
<product id="P002" sku="BOOK-001" category="books">
<name>XML入門書</name>
</product>
</products>
ベストプラクティス

1. 明確な命名規則
推奨:複数形の親要素
<products> <!-- 複数形 -->
<product> <!-- 単数形 -->
...
</product>
</products>
<employees> <!-- 複数形 -->
<employee> <!-- 単数形 -->
...
</employee>
</employees>
2. 適切な階層設計
良い例:論理的な階層
<company>
<departments>
<department name="営業部">
<teams>
<team name="第一営業チーム">
<members>
<member role="leader">田中太郎</member>
<member role="member">佐藤花子</member>
</members>
</team>
</teams>
</department>
</departments>
</company>
3. 一貫性のある構造
悪い例:構造が不統一
<data>
<item1>商品A</item1>
<product name="商品B"/>
<element>
<name>商品C</name>
</element>
</data>
良い例:構造が統一
<products>
<product name="商品A"/>
<product name="商品B"/>
<product name="商品C"/>
</products>
まとめ
今回は「XMLの繰り返し要素」について詳しく解説しました。
重要なポイント
- 繰り返し要素の基本概念
- 同じタグを複数並べることで配列やリストを表現
- 親要素の下に同じ構造の子要素を配置
- プログラミング言語の配列と同じような役割
- 正しい書き方を理解する
- 必ずタグを閉じる
- 適切にインデントする
- 意味のある要素名を使う
- よくある間違いを避ける
- タグの閉じ忘れに注意
- 意味のない繰り返しは避ける
- 構造の一貫性を保つ
- XMLスキーマで制約を定義
- minOccurs と maxOccurs で回数を制御
- データの妥当性を保証
繰り返し要素の活用指針
用途 | 推奨度 | 理由 |
---|---|---|
商品リスト | ★★★ | 同じ構造のデータの羅列に最適 |
ユーザー一覧 | ★★★ | 管理データの表現に適している |
設定項目 | ★★☆ | 複数の設定を整理しやすい |
ログデータ | ★★★ | 時系列データの表現に便利 |
単一データ | ★☆☆ | 繰り返しの必要がない場合は不要 |
コメント