#php #xml
#php #xml
Вопрос:
Я хотел бы спросить, как легко добавить новый узел в конец найденного узла в php. Допустим, у меня есть xml, подобный этому:
<Root>
<child id=1>
<text>smth</text>
</child>
</Root>
Я хочу найти дочерний элемент с идентификатором 1, а затем добавить другой узел в качестве последнего.
Я пытался найти ответ, но он либо отвечал, как его найти, либо как записать в него, к сожалению, я не смог собрать его вместе.
Я был бы очень рад, если кто-нибудь сможет мне с этим помочь.
Комментарии:
1. Вы пытались написать какой-нибудь код? Даже что-то базовое…
2. Здравствуйте, да, но я всегда заканчиваю тем, что нахожу Элемент, но не знаю, как добавить к нему дочерний элемент. Я пробовал DOMDocument и simplexml_load_file
3. simplexmlelement имеет
addChild()
метод4. @JOUM, вы можете проверить ответ, который я только что добавил 🙂
Ответ №1:
Вы можете использовать xpath
, чтобы найти соответствующий узел (на основе id
), а затем использовать addChild
, чтобы добавить новый дочерний узел к узлу, который вы только что нашли:
$str =<<< END
<Root>
<child id="1">
<text>smth</text>
</child>
</Root>
END;
$result = simplexml_load_string($str);
$child = $result->xpath("*[@id='1']")[0];
$child->addChild('text', 'node value');
// The part from here is only to make the output pretty-xml
// instead you can just use $result->saveXML()
$dom = new DOMDocument("1.0");
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($result->saveXML());
var_dump($dom->saveXML());
Результат будет:
string(115) "<?xml version="1.0"?>
<Root>
<child id="1">
<text>smth</text>
<text>node value</text>
</child>
</Root>
"
Комментарии:
1. Хорошо, может ли это обрабатывать огромные файлы (ГБ ) и подузлы? XmlReader / Writer также пришел мне на ум 🙂
2. Не пробовал этого, но я думаю, что при достаточном количестве процессора / оперативной памяти это должно сработать;)
3. в некоторых случаях simplexml требуется в 10 раз больше памяти, чем дисковое пространство, зависит от размера и структуры.
4. Не пробовал это для файлов объемом более ГБ… может быть, я когда-нибудь это сделаю.
5. Здравствуйте, большое спасибо за ответ, он работает так, как я надеялся.
Ответ №2:
В DOM вы используете Xpath для поиска узлов, DOMDocument::create*()
для создания узлов и подобных методов DOMNode::appendChild()
, чтобы поместить их в документ.
$xml =<<< END
<Root>
<child id="1">
<text>smth</text>
</child>
</Root>
END;
$document = new DOMDocument("1.0");
$document->preserveWhiteSpace = false;
$document->formatOutput = true;
$document->loadXml($xml);
$xpath = new DOMXpath($document);
foreach ($xpath->evaluate('//*[@id="1"][1]') as $parentNode) {
$parentNode
->appendChild($document->createElement('text'))
->appendChild($document->createTextNode('node value'));
}
echo $document->saveXML();
Вывод:
<?xml version="1.0"?>
<Root>
<child id="1">
<text>smth</text>
<text>node value</text>
</child>
</Root>
Для больших XML-файлов вы можете использовать XmlReader / XmlWriter, но вы не можете изменять документ. Вам нужно будет прочитать оригинал шаг за шагом и написать измененную копию.