残念ながらSimpleXMLElement
は、2つの要素を一緒に持って来るために何を提供していません。 @nickf wroteのように、それは操作よりも読みに適しています。ただし、姉妹の内線番号DOMDocument
は編集用です。dom_import_simplexml()
で両方を一緒に持ち込むことができます。 @salathe shows in a related answerこれは特定のSimpleXMLElementsでどのように動作するのですか?
入力チェックといくつかのオプションでこれがどのように機能するかを以下に示します。私は2つの例でそれを行います。
/**
* Insert XML into a SimpleXMLElement
*
* @param SimpleXMLElement $parent
* @param string $xml
* @param bool $before
* @return bool XML string added
*/
function simplexml_import_xml(SimpleXMLElement $parent, $xml, $before = false)
{
$xml = (string)$xml;
// check if there is something to add
if ($nodata = !strlen($xml) or $parent[0] == NULL) {
return $nodata;
}
// add the XML
$node = dom_import_simplexml($parent);
$fragment = $node->ownerDocument->createDocumentFragment();
$fragment->appendXML($xml);
if ($before) {
return (bool)$node->parentNode->insertBefore($fragment, $node);
}
return (bool)$node->appendChild($fragment);
}
この例示的な機能は、XMLを追加またはルート要素を含む、特定の要素の前に挿入することを可能にする:最初の例では、XML文字列を挿入する機能です。追加するものがあるかどうかを確認した後、DOMDocumentの機能を使用して、XMLをドキュメントフラグメントとして挿入します。How to import XML string in a PHP DOMDocumentにも概要が示されています。これは次のような出力が得られる
$parent = new SimpleXMLElement('<parent/>');
// insert some XML
simplexml_import_xml($parent, "\n <test><this>now</this></test>\n");
// insert some XML before a certain element, here the first <test> element
// that was just added
simplexml_import_xml($parent->test, "<!-- leave a comment -->\n ", $before = true);
// you can place comments above the root element
simplexml_import_xml($parent, "<!-- this works, too -->", $before = true);
// but take care, you can produce invalid XML, too:
// simplexml_add_xml($parent, "<warn><but>take care!</but> you can produce invalid XML, too</warn>", $before = true);
echo $parent->asXML();
:使用例
<?xml version="1.0"?>
<!-- this works, too -->
<parent>
<!-- leave a comment -->
<test><this>now</this></test>
</parent>
を第二の例では、SimpleXMLElement
挿入されます。必要に応じて、最初の関数を使用します。基本的には、何かするべきことがあり、どの種類の要素がインポートされるかをチェックします。
/**
* Insert SimpleXMLElement into SimpleXMLElement
*
* @param SimpleXMLElement $parent
* @param SimpleXMLElement $child
* @param bool $before
* @return bool SimpleXMLElement added
*/
function simplexml_import_simplexml(SimpleXMLElement $parent, SimpleXMLElement $child, $before = false)
{
// check if there is something to add
if ($child[0] == NULL) {
return true;
}
// if it is a list of SimpleXMLElements default to the first one
$child = $child[0];
// insert attribute
if ($child->xpath('.') != array($child)) {
$parent[$child->getName()] = (string)$child;
return true;
}
$xml = $child->asXML();
// remove the XML declaration on document elements
if ($child->xpath('/*') == array($child)) {
$pos = strpos($xml, "\n");
$xml = substr($xml, $pos + 1);
}
return simplexml_import_xml($parent, $xml, $before);
}
この典型的な機能は、要素のリストを正規化して行います。それは属性である場合、それはちょうどそれが要素である場合、それはXMLにシリアライズして、XMLとしての親要素に追加され、それを追加しますSimplexmlに共通する属性一度に複数のSimpleXMLElementsを挿入するためにそれを変更したい場合がありますが、使用例は、以下に示すように、私の例は、(属性の例を参照)ことをサポートしていません。
// append the element itself to itself
simplexml_import_simplexml($parent, $parent);
// insert <this> before the first child element (<test>)
simplexml_import_simplexml($parent->children(), $parent->test->this, true);
// add an attribute to the document element
$test = new SimpleXMLElement('<test attribute="value" />');
simplexml_import_simplexml($parent, $test->attributes());
echo $parent->asXML();
これは最初のusage-の続きです例。したがって出力は次のようになります。
<?xml version="1.0"?>
<!-- this works, too -->
<parent attribute="value">
<!-- leave a comment -->
<this>now</this><test><this>now</this></test>
<!-- this works, too -->
<parent>
<!-- leave a comment -->
<test><this>now</this></test>
</parent>
</parent>
これは役に立ちます。 find the code in a gistとonline demo/PHP version overviewとすることができます。
幸いにも、私はDOM(おそらく1時間かかります)にすべてのものを変換することによってあまりにも多くの時間を無駄にしないように十分早いです。他の誰かが本当にすばらしいアイデアを持っていない限り、これは私がおそらく終わらせる解決策だと思います。 答えをありがとう! – thomasrutter
私は同じ問題を抱えていました。 DOMに切り替えて、それははるかに良いです。 – Keyo