XMLのタグ内で改行する方法|見た目の整え方と注意点

Web

「XMLを書いていて、タグの中で改行したらちゃんと扱われるの?」
「複数行のテキストを入れたいけど、どう書けばいいの?」

XMLはデータを構造的に管理するのに便利ですが、タグ内の改行やインデントで思わぬ動きをすることもあります。

この記事では、XMLでタグ内を改行するとどう扱われるのか、見た目を整えるインデントのコツ、改行をそのまま保持する方法を初心者向けにわかりやすく解説します。

スポンサーリンク

XMLでの改行と空白の基本ルール

XMLパーサーによる空白の処理

XMLを処理するプログラム(XMLパーサー)は、一般的に以下のルールで空白文字を扱います:

  • 連続する空白文字:1つの半角スペースに統合
  • 行頭・行末の空白:削除される場合が多い
  • タグ間の空白:多くの場合無視される
  • 改行文字:半角スペースに変換される場合が多い

空白文字の種類

XMLで扱われる主な空白文字:

文字名称Unicode説明
半角スペースU+0020最も一般的な空白文字
\tタブU+0009インデントによく使用
\n改行(LF)U+000AUnix系の改行文字
\r復帰(CR)U+000D旧Mac系の改行文字
\r\nCR+LFWindows系の改行文字

タグ内での改行の動作

基本的な改行の扱い

例1:タグ内に改行を含む場合

<description>
  これは
  テストです。
</description>

パーサーでの処理結果

多くのXMLパーサーでは、このデータは以下のように処理されます:

  これは テストです。
  • 改行文字が半角スペースに変換
  • インデントの空白も保持される

例2:より複雑な改行パターン

<poem>
春が来た
春が来た
どこに来た
山に来た
里に来た
野にも来た
</poem>

この場合の処理結果:

春が来た 春が来た どこに来た 山に来た 里に来た 野にも来た

すべての改行が半角スペースに変換されてしまいます。

インデントとフォーマッティング

見た目を整えるインデント

XMLファイルの可読性を高めるために、以下のようなインデントを使用するのは一般的です:

<?xml version="1.0" encoding="UTF-8"?>
<library>
  <book id="001">
    <title>XMLプログラミング入門</title>
    <author>
      <name>山田太郎</name>
      <nationality>日本</nationality>
    </author>
    <publisher>技術出版社</publisher>
    <price currency="JPY">3200</price>
  </book>
  <book id="002">
    <title>データベース設計の基礎</title>
    <author>
      <name>佐藤花子</name>
      <nationality>日本</nationality>
    </author>
    <publisher>DB出版</publisher>
    <price currency="JPY">2800</price>
  </book>
</library>

インデントの推奨方法

スペースを使用(推奨)

  • 2スペースまたは4スペースが一般的
  • タブ文字よりも環境依存が少ない

一貫性を保つ

  • プロジェクト全体で同じインデント方法を使用
  • 自動フォーマッターの活用を検討

改行を確実に保持する方法

方法1:文字実体参照を使用

改行文字の文字実体参照

<message>こんにちは&#10;お元気ですか?&#10;今日もいい天気ですね。</message>

主な改行関連の文字実体参照

文字実体参照文字説明
&#10;LFUnix系の改行
&#13;CR旧Mac系の改行
&#13;&#10;CRLFWindows系の改行

実用例

<address>
  〒100-0001&#10;
  東京都千代田区千代田1-1&#10;
  皇居前ビル3F
</address>

方法2:CDATAセクションを使用

CDATAセクションとは

CDATA(Character Data)セクションは、XML parser が内容を解析せずにそのまま文字データとして扱う領域です。

基本的な書き方

<description>
<![CDATA[
これは複数行の
テキストです。

改行や空白も
そのまま保持されます。
]]>
</description>

CDATAセクションの特徴

メリット

  • 改行や空白がそのまま保持される
  • HTMLタグやXMLタグをそのまま書ける
  • エスケープ処理が不要

注意点

  • ]]>という文字列は使用できない
  • CDATAセクション内では文字実体参照は使用不可
  • ネストはできない

実用例:HTMLコードの格納

<template>
<![CDATA[
<div class="container">
  <h1>タイトル</h1>
  <p>これは段落です。<br>
     改行も含まれています。</p>
</div>
]]>
</template>

実用例:プログラムコードの格納

<code language="javascript">
<![CDATA[
function greet(name) {
  console.log("Hello, " + name + "!");
  
  if (name === "World") {
    return "Welcome!";
  }
  
  return "Nice to meet you!";
}
]]>
</code>

方法3:xml:spaceアトリビュートを使用

xml:spaceアトリビュートとは

XMLの標準的な属性で、空白文字の処理方法を指定できます。

使用方法

<poem xml:space="preserve">
春が来た
春が来た
どこに来た
山に来た
里に来た
野にも来た
</poem>

xml:spaceの値

説明
default通常の空白処理(デフォルト)
preserve空白をそのまま保持

実用例

<document>
  <normal-text>この文章では通常の空白処理が適用されます。</normal-text>
  
  <formatted-text xml:space="preserve">
    このテキストでは
    改行と    空白が
    そのまま保持されます。
  </formatted-text>
</document>

属性値での改行処理

属性値の制限事項

XMLの属性値では改行を直接記述することはできません。

間違った例

<!-- これはエラーになります -->
<user name="田中
太郎" age="30" />

正しい例

<!-- 改行が必要なデータは要素として記述 -->
<user age="30">
  <name>田中
太郎</name>
</user>

属性値で改行を表現したい場合

文字実体参照を使用

<message text="1行目&#10;2行目&#10;3行目" />

ただし、この方法はあまり推奨されません。可読性が悪く、保守が困難になります。

推奨されるアプローチ

<message>
  <line>1行目</line>
  <line>2行目</line>
  <line>3行目</line>
</message>

または

<message>
<![CDATA[1行目
2行目
3行目]]>
</message>

プログラミング言語での処理例

Python での例

import xml.etree.ElementTree as ET

# XMLデータ
xml_data = '''
<document>
  <normal>これは
  普通のテキストです。</normal>
  
  <with-cdata>
  <![CDATA[これは
  CDATAセクション内の
  テキストです。]]>
  </with-cdata>
  
  <with-entity>改行あり&#10;テキストです。</with-entity>
</document>
'''

# パース
root = ET.fromstring(xml_data)

# 各要素のテキストを確認
for child in root:
    print(f"{child.tag}: '{child.text}'")
    print(f"改行文字数: {child.text.count(chr(10))}")
    print("---")

実行結果

normal: 'これは
  普通のテキストです。'
改行文字数: 1
---
with-cdata: 'これは
  CDATAセクション内の
  テキストです。'
改行文字数: 2
---
with-entity: '改行あり
テキストです。'
改行文字数: 1
---

JavaScript での例

const xmlString = `
<document>
  <message xml:space="preserve">
    複数行の
    メッセージです。
  </message>
</document>
`;

const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, "text/xml");

const messageElement = xmlDoc.querySelector('message');
const text = messageElement.textContent;

console.log("原文:", text);
console.log("改行の数:", (text.match(/\n/g) || []).length);

// 改行を<br>タグに変換してHTMLで表示
const htmlText = text.replace(/\n/g, '<br>');
console.log("HTML形式:", htmlText);

ツール別の改行処理

エディタでの表示

Visual Studio Code

拡張機能「XML Tools」を使用

  • XMLの構文ハイライト
  • 自動インデント機能
  • CDATAセクションの識別

設定例

{
  "xml.format.enabled": true,
  "xml.format.splitAttributes": false,
  "xml.format.preserveEmptyContent": true
}

Notepad++

XMLプラグインの活用

  • XML整形機能
  • CDATAセクションの色分け
  • 改行文字の可視化

ブラウザでの表示

Chrome/Edge

XMLファイルをブラウザで直接開いた場合:

  • CDATAセクション内の改行は保持される
  • 通常の要素内の改行は無視される場合が多い

Firefox

  • より忠実にXMLの改行を表示する傾向
  • 開発者ツールでの確認が便利

XMLプロセッサーでの処理

XSLT での処理

<xsl:template match="poem">
  <div class="poem">
    <xsl:value-of select="." />
  </div>
</xsl:template>

改行を保持してHTMLに変換したい場合:

<xsl:template match="poem">
  <div class="poem">
    <xsl:call-template name="replace-newlines">
      <xsl:with-param name="text" select="." />
    </xsl:call-template>
  </div>
</xsl:template>

<xsl:template name="replace-newlines">
  <xsl:param name="text" />
  <xsl:choose>
    <xsl:when test="contains($text, '&#10;')">
      <xsl:value-of select="substring-before($text, '&#10;')" />
      <br />
      <xsl:call-template name="replace-newlines">
        <xsl:with-param name="text" select="substring-after($text, '&#10;')" />
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$text" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

ベストプラクティス

改行処理の方針決定

プロジェクト開始時に決めること

  1. 改行の扱い方
    • データとして重要か、単なる見た目か
    • 対象システムでの処理方法
  2. フォーマット規則
    • インデント方法(スペース数、タブの使用可否)
    • 要素の配置ルール
  3. CDATAセクションの使用基準
    • どのようなデータでCDATAを使用するか
    • 代替手段との使い分け

推奨されるアプローチ

データ型に応じた選択

短いテキスト(1行程度)

<title>XMLプログラミング入門</title>

複数行だが構造的でないテキスト

<description xml:space="preserve">
商品説明:
この商品は高品質な素材を使用し、
長期間の使用に耐える設計となっています。

特徴:
- 耐久性抜群
- 環境に優しい
- リーズナブルな価格
</description>

HTMLやコードなどの特殊文字を含むデータ

<template>
<![CDATA[
<div class="product">
  <h2>{{title}}</h2>
  <p>{{description}}</p>
  <span class="price">${{price}}</span>
</div>
]]>
</template>

構造化されたテキストデータ

<address>
  <postal-code>100-0001</postal-code>
  <prefecture>東京都</prefecture>
  <city>千代田区</city>
  <street>千代田1-1</street>
  <building>皇居前ビル3F</building>
</address>

避けるべきパターン

アンチパターン1:属性での複雑なデータ

<!-- 悪い例 -->
<item data="名前:田中太郎&#10;年齢:30&#10;職業:エンジニア" />

<!-- 良い例 -->
<item>
  <name>田中太郎</name>
  <age>30</age>
  <occupation>エンジニア</occupation>
</item>

アンチパターン2:不適切なCDATAの使用

<!-- 悪い例 -->
<price><![CDATA[3000]]></price>

<!-- 良い例 -->
<price>3000</price>

アンチパターン3:一貫性のないフォーマット

<!-- 悪い例 -->
<book>
<title>タイトル1</title>
  <author>著者1</author>
    <price>1000</price>
</book>

<!-- 良い例 -->
<book>
  <title>タイトル1</title>
  <author>著者1</author>
  <price>1000</price>
</book>

まとめ

XMLでの改行処理のポイント

基本的な理解

  1. 通常の改行:多くの場合、半角スペースに変換される
  2. インデント:見た目を整える目的なら自由に使用可能
  3. データとしての改行:特別な方法で明示的に指定する必要がある

改行を保持する3つの方法

方法使用場面メリットデメリット
文字実体参照短いテキスト軽量、確実可読性が悪い
CDATAセクション長いテキスト、特殊文字自然な書き方XMLの利点の一部を放棄
xml:space属性標準準拠が重要標準的な方法対応していないパーサーもある

コメント

タイトルとURLをコピーしました