Intereting Posts
mysql_affected_rows () возвращает 0 для инструкции UPDATE, даже если обновление действительно происходит Лучший способ отключить несколько элементов массива PHP textarea сохраняет дополнительные новые строки в MySQL DB Как перейти на другую страницу при выполнении PHP-скрипта? Как добавить новый модуль в администрацию opencart? Не разрешать> 2mb изображения Выполняется ли выполнение php после того, как пользователь покидает страницу? Я получаю сообщение об ошибке «Не удалось получить», когда я использую mail () в php Хранение переменной php $ _GET в переменной javascript? Неустранимая ошибка: вызов неопределенного метода mysqli_stmt :: get_result () Маршрутизатор Phalcon не реагирует на вложенные папки и декларацию пространства имен Как получить тело сообщения и вложения в формате XML, используя php / linux с сервера Lotus Domino? Добавить вызов видео и голосового вызова на мой сайт php Запуск PHP после запроса Преобразование элемента DOM в строку в PHP

Использование DOMXml и Xpath для обновления записей XML

Здравствуйте, я знаю, что здесь есть много вопросов об этих трех темах, объединенных вместе для обновления XML-записей, но, похоже, все очень специфичны для данной проблемы.

Я проводил некоторое время, пытаясь понять XPath и его путь, но я все еще не могу получить то, что мне нужно сделать.

Вот так

У меня есть этот XML-файл

<?xml version="1.0" encoding="UTF-8"?> <storagehouse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema.xsd"> <item id="c7278e33ef0f4aff88da10dfeeaaae7a"> <name>HDMI Cable 3m</name> <weight>0.5</weight> <category>Cables</category> <location>B3</location> </item> <item id="df799fb47bc1e13f3e1c8b04ebd16a96"> <name>Dell U2410</name> <weight>2.5</weight> <category>Monitors</category> <location>C2</location> </item> </storagehouse> 

Я хотел бы сделать это, чтобы обновить / изменить любой из вышеперечисленных узлов, когда мне это нужно. Я сделаю для этого Html-форму. Но моя самая большая проблема заключается в том, как найти и обновить нужный узел и обновить его?

Здесь у меня есть кое-что из того, что я пытаюсь сделать

 <?php function fnDOMEditElementCond() { $dom = new DOMDocument(); $dom->load('storage.xml'); $library = $dom->documentElement; $xpath = new DOMXPath($dom); // I kind of understand this one here $result = $xpath->query('/storagehouse/item[1]/name'); //This one not so much $result->item(0)->nodeValue .= ' Series'; // This will remove the CDATA property of the element. //To retain it, delete this element (see delete eg) & recreate it with CDATA (see create xml eg). //2nd Way //$result = $xpath->query('/library/book[author="JRRTolkein"]'); // $result->item(0)->getElementsByTagName('title')->item(0)->nodeValue .= ' Series'; header("Content-type: text/xml"); echo $dom->saveXML(); } ?> 

Может кто-нибудь может дать мне примеры с атрибутами и т. Д., Поэтому один пользователь решает обновить нужный узел, я мог бы найти этот узел с XPath, а затем обновить его?

В следующем примере используется simplexml который является близким другом DOMDocument . Отображение xpath одинаково независимо от того, какой метод вы используете, и я использую simplexml здесь, чтобы сохранить код низким. В дальнейшем я покажу более продвинутый пример DOMDocument .

Итак, о xpath: как найти узел и обновить его. Прежде всего, как найти узел:

У узла есть элемент / тэг. Вы ищете его внутри элемента storagehouse , который является корневым элементом вашего XML-документа. Все элементы элемента в вашем документе выражаются следующим образом в xpath:

 /storagehouse/item 

Из корня, первого storagehouse , затем item . Разделен на / . Вы уже знаете это, поэтому интересная часть состоит в том, как принимать только те элементы элементов, которые имеют конкретный идентификатор. Для этого предикат используется и добавляется в конце:

 /storagehouse/item[@id="id"] 

Это вернет все элементы элемента снова, но на этот раз будут только те, у которых есть id атрибута id (строка). Например, в вашем случае со следующим XML:

 $xml = <<<XML <?xml version="1.0" encoding="UTF-8"?> <storagehouse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema.xsd"> <item id="c7278e33ef0f4aff88da10dfeeaaae7a"> <name>HDMI Cable 3m</name> <weight>0.5</weight> <category>Cables</category> <location>B3</location> </item> <item id="df799fb47bc1e13f3e1c8b04ebd16a96"> <name>Dell U2410</name> <weight>2.5</weight> <category>Monitors</category> <location>C2</location> </item> </storagehouse> XML; 

что xpath:

 /storagehouse/item[@id="df799fb47bc1e13f3e1c8b04ebd16a96"] 

вернет монитор компьютера (потому что такой элемент с этим идентификатором существует). Если бы было несколько элементов с одинаковым значением id, то было бы возвращено несколько. Если их не было, никто не будет возвращен. Итак, давайте обернем это в пример кода:

 $simplexml = simplexml_load_string($xml); $result = $simplexml->xpath(sprintf('/storagehouse/item[@id="%s"]', $id)); if (!$result || count($result) !== 1) { throw new Exception(sprintf('Item with id "%s" does not exists or is not unique.', $id)); } list($item) = $result; 

В этом примере $titem является объектом SimpleXMLElement этого элемента элемента элемента xml монитора компьютера.

Итак, теперь для изменений, которые чрезвычайно SimpleXML при использовании SimpleXML в вашем случае:

 $item->category = 'LCD Monitor'; 

И, наконец, увидеть результат:

 echo $simplexml->asXML(); 

Да, это все с SimpleXML в вашем случае.

Если вы хотите сделать это с помощью DOMDocument , это работает очень похоже. Однако для обновления значения элемента вам необходимо также получить доступ к дочернему элементу этого элемента. Давайте посмотрим следующий пример, который в первую очередь извлекает элемент. Если вы сравните с SimpleXML выше примером SimpleXML , вы увидите, что вещи на самом деле не отличаются:

 $doc = new DOMDocument(); $doc->loadXML($xml); $xpath = new DOMXPath($doc); $result = $xpath->query(sprintf('/storagehouse/item[@id="%s"]', $id)); if (!$result || $result->length !== 1) { throw new Exception(sprintf('Item with id "%s" does not exists or is not unique.', $id)); } $item = $result->item(0); 

Опять же, $item содержит элемент XML элемента монитора компьютера. Но на этот раз как DOMElement . Чтобы изменить элемент category (или, точнее, nodeValue ), сначала нужно получить детей. Вы можете сделать это снова с помощью xpath, но на этот раз с выражением относительно элемента $item :

 ./category 

Предполагая, что в item элемента всегда есть дочерний элемент category , это может быть записано как таковое:

 $category = $xpath->query('./category', $item)->item(0); 

$category теперь содержит дочерний элемент первой category из $item . Осталось обновить его значение:

 $category->nodeValue = "LCD Monitor"; 

И, наконец, увидеть результат:

 echo $doc->saveXML(); 

Вот и все. Независимо от того, выбираете ли вы SimpleXML или DOMDocument, это зависит от ваших потребностей. Вы даже можете переключаться между ними. Возможно, вам захочется отобразить и проверить изменения:

 $repository = new Repository($xml); $item = $repository->getItemByID($id); $item->category = 'LCD Monitor'; $repository->saveChanges(); echo $repository->getXML(); 

Естественно, это требует большего количества кода , что слишком много для этого ответа.