私は外部のベンダーにXML文書を送信していますが、そのうちの1つはXMLコンテンツの中に一重引用符と二重引用符があるため、XMLの解析に問題があります。公式のXML仕様では、属性で使用するとエスケープする必要があるだけですが、PHPのSimpleXMLElementを拡張して引用符をエスケープするのはあまり難しくないと思いました。これはそうではありませんでした。PHPのSimpleXMLElementを拡張する
<?php
class BetterXMLElement extends SimpleXMLElement
{
public function __set($name, $value)
{
echo "called __set with $name and $value";
$this->addChild($name, $value);
}
public function addChild($name, $value=null, $ns=null)
{
$new_value = strtr($value, [
'&' => '&',
'"' => '"',
"'" => ''',
]);
echo "New Value: $new_value\n";
parent::addChild($name, $new_value, $ns);
}
}
$xml = new BetterXMLElement('<?xml version="1.0" encoding="UTF-8"?><TRANSACTION></TRANSACTION>');
$xml->COST = "apos: ', amp: &, quot: \"";
$xml->addChild('PRODUCT', "apos: ', amp: &, quot: \"");
echo $xml->asXML();
上記のコードの出力:これは私に示して何
New Value: apos: ', amp: &, quot: "
<?xml version="1.0" encoding="UTF-8"?>
<TRANSACTION><COST>apos: ', amp: &, quot: "</COST><PRODUCT>apos: ', amp: &, quot: "</PRODUCT></TRANSACTION>
は次のとおりです。
- 私と同じように
__set
でエコーが、呼び出されていない私の最初の試みは、このました私がCOSTを設定しているときであることを期待してください。なぜこれは機能しないのですか? - PRODUCTを設定すると、addChildのオーバーライドが呼び出されていますが、asXMLが呼び出されると、引用符のHTMLエンティティが変換されて戻ってきます。なぜそれはこのように機能するのですか?それを無効にする方法はありますか?
問題を再現する方法を示すコードサンプルが参考になります。 –
@JakubMatczak良い点、私はいくつかの使用例と出力を追加しました! –
'SimpleXMLElement'クラスは通常のクラスではありません。それはクラスのように見えますが、それは規則的ではない方法で多くのことを行います。代わりに 'DOMDocument'を使うことをお勧めします。これは、['loadXML()'](http://php.net/manual/en/domdocument.loadxml.php)と['saveXML()'](http://php.net/manual/en/)を提供します。 domdocument.savexml.php)を使用して、ドキュメントをXMLテキストとしてシリアル化し、その内容を検査および変更するための多くのメソッドを使用できます。 – axiac