0

私はxmlfileを持っています:

$xml = <<<EOD
<?xml version="1.0" encoding="utf-8"?>
<metaData xmlns="http://www.test.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="test">
<qkc6b1hh0k9>testdata&amp;more</qkc6b1hh0k9>
</metaData>
EOD;

今私はそれをsimplexmlobjectにロードし、後で「qkc6b1hh0k9」ノードの内部を取得したかった

$xmlRootElem = simplexml_load_string( $xml );
$xmlRootElem->registerXPathNamespace( 'xmlns', "http://www.test.com/" );

// ...

$xPathElems = $xmlRootElem->xpath( './'."xmlns:qkc6b1hh0k9" );
$var = (string)($xPathElems[0]);
var_dump($var);

文字列を取得することを期待していました

testdata&amp;more

...しかし、私は得ました

testdata&more
  • simplexmlobject の __toString() メソッドが、エスケープされた特殊文字を通常の文字に変換するのはなぜですか? この動作を無効にすることはできますか?
  • 私は一時的な解決策を思いつきましたが、それは汚いと思いますが、どう思いますか?

    (strip_tags($xPathElems[0]->asXML()))

  • DOMDocument が代わりになることはありますか?

私の質問に助けてくれてありがとう!

編集

問題は解決しました。問題は simplexml の __toString メソッドにはありませんでした。後で addChild で文字列を使用したときに発生しました。

上記の動作はまったく問題なく、回答でわかるように期待する必要があります...

「addChild」を介して値が別のxmlドキュメントに追加されたときにのみ問題が発生しました。addChild はアンパサンド ( http://www.php.net/manual/de/simplexmlelement.addchild.php#103587 )をエスケープしないため、手動で行う必要があります。

4

2 に答える 2

2

simplexmlobject の __toString() メソッドが、エスケープされた特殊文字を通常の文字に変換するのはなぜですか? この動作を無効にすることはできますか?

これらの「特別な」文字は、実際には文字の XML エンコードであるためです。文字列値を使用すると、これらの文字が再び逐語的に得られます。それが、XML パーサーが作成された目的です。

私は一時的な解決策を思いつきましたが、それは汚いと思いますが、どう思いますか?

うーん、ぐらぐら。代わりに、逆の方法をお勧めします。XML で文字列をエンコードします。

$var = htmlspecialchars($xPathElems[0]);
var_dump($var);

DOMDocument が代わりになることはありますか?

いいえ、SimpleXML は XML パーサーであるため、テキストもデコードされます。これは完全に正しいわけではありません ( DomDocument では、すべての子ノードを調べて、文字データの横にあるエンティティ ノードを選択することでこれを行うことができますが、上記の htmlspecialchars() で概説したように、はるかに多くの作業が必要です)

于 2013-04-18T22:50:48.793 に答える
1

適切な方法で XML タグを作成し、文字列 を含むように設定すると"testdata&more"、これは としてエスケープされtestdata&amp;moreます。したがって、その文字列コンテンツを抽出して元に戻すと、エスケープ手順が逆になり、入力したテキストが得られるのは論理的です。

問題は、なぜ XML エスケープ表現が必要なのかということです。作成者が意図したとおりに要素のコンテンツが必要な場合__toString()は、正しいことを行っています。XML でその文字列を表現する方法は複数ありますが、通常気にする必要があるのは表現されるデータです。

何らかの理由で、特定のインスタンスでXML がどのように構築されているかの詳細が本当に必要な場合は、DOM などのより複雑な解析フレームワークを使用できます。これはtestdata&amp;more、テキスト ノード (「testdata」を含む)、エンティティ ノード (を含む) に分割されます。名前「amp」)、および別のテキスト ノード (「more」を含む)。

一方、それを別の XML (または HTML) ドキュメントに戻すことだけが必要な場合は、SimpleXML で適切にアンエスケープを行い、適切なタイミングで再度エスケープします。

于 2013-04-18T19:31:25.310 に答える