1

テーブルデータを xml にエクスポートしています。これには、コンテンツ列に多言語コンテンツが含まれており、html が混在しています。

$xmlWriter->writeAttribute('value', $contents);

記録:

name="testing" , contents="Just <span style="color:red">testing</span>:漢字"

次の形式でエクスポート:

<entry key="testing" value="Just &lt;span style='color:red'&gt;testing&lt;/span&gt;:&#x6F22;&#x5B57;">

期待される:

<entry key="testing" value="Just &lt;span style='color:red'&gt;testing&lt;/span&gt;:漢字">

xml ライターに多言語文字をエンコードさせたくないのですが、どうすれば可能ですか?

4

1 に答える 1

3

xml ライターに多言語文字をエンコードさせたくないのですが、どうすれば可能ですか?

実際、XML を作成すると、すでにエンコードされています。つまり、これらの 2 つの文字に数値エンティティを使用したくないということです。これは可能ですが、常にではありません。

数値エンティティを使用しないようにするには、ドキュメントのエンコーディングを文字列のエンコーディングと一致させる必要があります。あなたが提供した出力から、私は少ししか推測できませんが、これらの2つの文字はおそらく次の略です:

  1. Unicode Han Character 'the Chinese people, Chinese language' (U+6F22)
  2. Unicode 漢字 '文字、文字、単語' (U+5B57)

これは (私は今のところ中国語を話せません) Chinese Wordのようなものを意味する可能性があります。

ドキュメントのエンコーディングがドキュメント内でその文字を表現できない場合はいつでも、PHPの XMLWriter は常に文字を数値エンティティに入れます(あなたの例では&#x6F22;とのように)。&#x5B57;

両方のエンコーディングを一致させることができる場合、XMLWriter は自動的に数値エンティティを使用しません。

もっと簡単な例を挙げます。属性値としてÄpfel ( Unicode Character 'LATIN CAPITAL LETTER A WITH DIAERESIS' (U+00C4) )からUS-ASCIIエンコードとドイツ語のウムラウトを取得しましょう。Ä

<?php
$xmlWriter = new XMLWriter();
$xmlWriter->openMemory();
$xmlWriter->startDocument('1.0', 'US-ASCII');
$xmlWriter->startElement('root');
$xmlWriter->writeAttribute('value', 'Äpfel');
$xmlWriter->endDocument();
echo $xmlWriter->flush();

UTF-8 でエンコードされた PHP ファイルに書き留められたこのコードは、実行時に次のように出力されます。

<?xml version="1.0" encoding="US-ASCII"?>
<root value="&#196;pfel"/>

&#196;は Unicode 文字 U+00C4 の数値エンティティであり、よく見ると、C4 は 10 進数 196 の 16 進数表現であり、数値 XML エンティティが常に Unicode 文字番号を表していることも示しています。

そのため、XML 出力は US-ASCII エンコーディングを使用します。これは、PHP コードで UTF-8 でエンコードされた文字列を表すことができないÄため、数値エンティティで適切にエンコードして文字情報を保持します。

エンコーディングを次から変更します。

$xmlWriter->startDocument('1.0', 'US-ASCII');

PHP 文字列の UTF-8 エンコーディングに:

$xmlWriter->startDocument('1.0', 'UTF-8');

この出力を変更します:

<?xml version="1.0" encoding="UTF-8"?>
<root value="Äpfel"/>

これはあなたの例でも同様に機能しますが、質問の重要な情報が1つ欠落しています:そのレコードの文字列はどのエンコーディングですか?

既に UTF-8 である場合は、上記の例で概説したように、既に機能しています。

<?php
$recordUTf8 = "... contents=\"Just <span style=\"color:red\">testing</span>:"
             ."\xE6\xBC\xA2\xE5\xAD\x97\"";
$encoding   = 'UTF-8';
$encoding   = 'US-ASCII';

$xmlWriter = new XMLWriter();
$xmlWriter->openMemory();
$xmlWriter->startDocument('1.0', $encoding);
$xmlWriter->startElement('record');
$xmlWriter->writeAttribute('value', $recordUTf8);
$xmlWriter->endDocument();
echo $xmlWriter->flush();

出力:

<?xml version="1.0" encoding="UTF-8"?>
<record value="... contents=&quot;Just &lt;span style=&quot;color:red&quot;&gt;
               testing &lt;/span&gt;:漢字 &quot;"/>

この出力が示すように、ここでは数値エンティティは使用されていませんが、文字列は明らかに UTF-8 でエンコードされています (PHP ファイルをコピーする場合に別のエンコードを使用する場合に備えて、ここではバイナリセーフな方法で)。

この時点で要約すると、XML エンコーディングは、文字列のエンコーディングと一致して、数値エンティティではないすべての文字を表す必要があります (XML 自体をエンコードするために使用される<>'"およびを除く&)。

これらはほとんど XML の基本です。ドキュメントに文字データを表現できないエンコーディングがある場合、XML は Unicode をサポートしているため、フォールバックは数値エンティティになります。ドキュメントのエンコーディングを文字列のエンコーディングに合わせることで、このフォールバックを防ごうとしています。

具体的には、PHP と XMLWriter に対する私のアドバイスは次のとおりです。

  1. データベースからレコードを取得するか、UTF-8 に再エンコードします。
  2. UTF-8 文字列のみをXMLWriterメソッドに渡します。
  3. XML ドキュメントのエンコーディングを UTF-8 に設定します。

UTF-8 は XML のデフォルトのエンコーディングであり、PHP では UTF-8 が十分にサポートされているため、これらの提案を行います。また、XMLWriter は Unicode 文字列が UTF-8 でエンコードされていることを想定しています。それを変更できる設定やオプションはないため、入力は既に UTF-8 でエンコードされている必要があります。

ただし、入力文字列とは関係なく、XMLWriter に別の出力エンコーディングを使用するように指示することは当然できます。たとえば、他の中国語または Unicode エンコーディングが適している可能性があり、PHP 構成がその特定の出力エンコーディングをサポートしている限り、XMLWriter 出力が可能です (持っている iconv ライブラリを確認してください)。

XMLWriter でドキュメントを開始する場合、2 番目のパラメーターでエンコーディングを指定します。

$xmlWriter->startDocument('1.0', $encoding);

対応する XML-Declaration で、XML がサポートするエンコーディングのセットから任意のエンコーディングを入れることができます。

<?xml version="1.0" encoding="ISO-8859-1"?><!-- Latin-1 example -->

XML エンコーディング値の完全な仕様は、http ://www.w3.org/TR/REC-xml/#NT-EncName ::にあります。

エンコーディング宣言では、値 " UTF-8"、" UTF-16"、" ISO-10646-UCS-2"、および " ISO-10646-UCS-4" を Unicode / ISO/IEC 10646 のさまざまなエンコーディングと変換に使用する必要があります。値 " ISO-8859-1"、" ISO-8859-2"、... " ISO-8859-n " (n はパーツ番号) は、ISO 8859 のパーツに使用する必要があり、値 " ISO-2022-JP"、" Shift_JIS"、および "EUC-JP" は、JIS X-0208-1997 のさまざまなエンコード形式に使用する必要があります。 インターネット割り当て番号機関 [IANA-CHARSETS] に (文字セットとして) 登録されている文字エンコードは、ここで挙げたもの以外は、次を使用して参照することをお勧めします。 XML プロセッサは、大文字と小文字を区別しない方法で文字エンコーディング名を照合し、IANA に登録された名前を IANA に登録されたその名前のエンコーディングとして解釈する必要があります。未知のものとして扱います (もちろん、プロセッサは IANA に登録されたすべてのエンコーディングをサポートする必要はありません)。

[IANA-CHARSETS] は次のとおりです。

(Internet Assigned Numbers Authority) Official Names for Character Sets編。ケルド・シモンセ​​ン 他 ( http://www.iana.org/assignments/character-setsを参照してください。)

これらの仕様は、おそらく少し冗長です。あなたの質問の文脈では、あなたがする必要があるのは、レコード文字列のエンコーディングを見つけることだけです。ところで。正確な出力を再現できなかったとは言えません。16 進数ではなく、常に 10 進数のエンティティを取得します。文字列の 16 進ダンプを使用して、より多くの情報を提供できる場合があります。

于 2013-09-19T09:37:21.097 に答える