0

私の Grails アプリケーションでは、Groovy のXmlParserを使用して XML ファイルを解析しています。私の XML ファイルの属性の 1 つの値は、文字の 16 進コードに等しい文字列です。その文字列をデータベースに保存したい:

Ñ

残念ながら、属性メソッドはÑ文字を返し、実際にデータベースに格納されるのは ですc391。フィールドが読み戻されると、望ましくないÑ文字も取得されます。

データベースに 16 進コードを文字列として保存し、16 進コードとして読み戻されるようにするにはどうすればよいですか?

更新 #1:

これが私にとって問題である理由は、XML ファイルをデータベースに読み取った後、それを元どおりに再構築できなければならないからです。追加の問題は、問題のフィールドが常に文字の 16 進コードであるとは限らないことです。任意の文字列である可能性があります。

更新 #2:

拡張された 16 進コード形式で文字を書き戻すことができる限り、文字がデータベースにどのように格納されているかは問題ではないと思います。Groovy MarkupBuilderを使用してデータベースから XML ファイルを再構築していますが、デフォルトでこれが行われない理由がわかりません。

更新 #3:

カスタムの MySQL ダイアレクトを上書きgetTableTypeStringしましたが、それが何かの助けになったようです。少なくとも、MySQL に渡す値は、データベースに格納される値です。

class CustomMySQL5InnoDBDialect extends MySQL5InnoDBDialect {   
    @Override
    public String getTableTypeString() {
        return " ENGINE=InnoDB DEFAULT CHARSET=utf8"
    }
}

独自のバージョンのgroovy.util.XmlParserも作成しました。私のバージョンは、私が変更した方法をgroovy.util.XmlParser除いて、ほぼ正確に複製されています。startElement

String value = list.getValue(i)

これに:

def value = list.fAttributes.fAttributes[i].nonNormalizedValue
if(value ==~ /&#x([0-9A-F]+?);/) {
    value = list.fAttributes.fAttributes[i].nonNormalizedValue
}

これにより、16 進コード要素の正確なテキストをデータベースに格納できます。

現在、2 つ、おそらく 3 つの新しい問題があります。

  1. データベースに保存されている正確な値でファイルを再作成します。これまでは を使用していましたがMarkupBuilder、アンパサンドで余分なエンコーディングを行っているため、XML 文字列を手動で 破棄して構築することでおそらくこれを回避できるため、値Ñが書き出されてしまいますが、むしろそうしたくありません。ÑMarkupBuilder

  2. Saxon-HE 9.4 プロセッサを使用して XML ファイルに対して XSLT 変換を実行すると、一部の 16 進コード値がÿÿのような値に変更されますが、その他の値は変更されません。™

  3. これが問題になるかどうかはまだわかりませんが、ファイルを再作成するときはANSI、元のファイルに使用されているエンコーディングであるため、エンコーディングにしたいと考えています。

4

2 に答える 2

0

XML ファイル内の属性の 1 つの値が、文字の 16 進コードに等しい文字列です。

いいえ、そうではありません。元の XML での属性値の表現は 16 進文字参照ですが、属性のは文字 Ñ です。一部の XML パーサーを構成して、解析中に名前付きエンティティ参照を展開しないようにする方法はありますが、XML 仕様に従って数値文字参照を展開する必要があります。

実際の文字値を保存することが問題である理由を述べていません。値をブラウザにレンダリングすることに関係している場合は.encodeAsHTML()、出力時に使用して処理できます。値を別の XML ファイルに保存する必要がある場合は、XML API を使用してこれを行うと、エンコーディングの問題が処理され、結果を整形式に保つために必要なエンティティまたは文字参照に文字が置き換えられます (例外的な文字セットで XML を記述していない限り、エスケープする必要はありません)。

Groovy の MarkupBuilder の特定のケースでは、一時的に XML モードから抜け出し、手作業で構築されたマークアップを を使用して出力ストリームに直接書き込むことができmkp.yieldUnescapedます。これにより、ビルダーが通常気にしない場所に文字参照を出力できます。

于 2013-09-27T09:49:27.777 に答える