Добавить новый узел в XML для каждого элемента с переменной в качестве атрибута, используя PHP - PullRequest
0 голосов
/ 21 марта 2019

Я немного потренировался с PHP и у меня есть несколько вопросов о том, как добавлять новые узлы в XML для каждого элемента с переменной в качестве атрибута с использованием PHP, я объясню это подробно.

Сначала язагрузить XML-файл, структура которого похожа на следующую:

<?xml version="1.0" encoding="utf-8"?>
<products>
  <item>
    <reference>00001</reference>
    <other_string>PRODUCT 1</other_string>
    <brand>BRAND 1</brand>
    <promo>YES</promo>
  </item>
  <item>
    <reference>00002</reference>
    <other_string>PRODUCT 2</other_string>
    <brand>BRAND 2</brand>
    <promo>YES</promo>
  </item>
  <item>
    <reference>00003</reference>
    <other_string>PRODUCT 3</other_string>
    <brand>BRAND 3</brand>
    <promo>NO</promo>
  </item>
  <item>
    <reference>00004</reference>
    <other_string>PRODUCT 4</other_string>
    <brand>BRAND 4</brand>
    <promo>NO</promo>
  </item>
  <item>
    <reference>00005</reference>
    <other_string>PRODUCT 5</other_string>
    <brand>BRAND 5</brand>
    <promo>YES</promo>
  </item>
</products>

И, как вы можете видеть, в XML есть узел с именем <promo></promo> с двумя возможными переменными «YES» и «NO», поэтомуна основании этого мне нужно создать новый узел, содержащий «1», если присутствует «YES», или «0», если «NO» будет выглядеть примерно так:

<?xml version="1.0" encoding="utf-8"?>
<products>
  <item>
    <reference>00001</reference>
    <other_string>PRODUCT 1</other_string>
    <brand>BRAND 1</brand>
    <promo>YES</promo>
    <newnode>1</newnode>
  </item>
  <item>
    <reference>00002</reference>
    <other_string>PRODUCT 2</other_string>
    <brand>BRAND 2</brand>
    <promo>YES</promo>
    <newnode>1</newnode>
  </item>
  <item>
    <reference>00003</reference>
    <other_string>PRODUCT 3</other_string>
    <brand>BRAND 3</brand>
    <promo>NO</promo>
    <newnode>0</newnode>
  </item>
  <item>
    <reference>00004</reference>
    <other_string>PRODUCT 4</other_string>
    <brand>BRAND 4</brand>
    <promo>NO</promo>
    <newnode>0</newnode>
  </item>
  <item>
    <reference>00005</reference>
    <other_string>PRODUCT 5</other_string>
    <brand>BRAND 5</brand>
    <promo>YES</promo>
    <newnode>1</newnode>
  </item>
</products>

Я играл с этим кодомно он не работает рекурсивно и кажется, что не определяет значения с помощью xPath:

<?php
$sXML = simplexml_load_file('file.xml', null, LIBXML_NOBLANKS);
$promoyes = $sXML->xpath("//item[promo='YES']");
foreach ( $promoyes as $value )    {
    $value = $sXML->item->addChild('newnode', '1');
}
unset($value);
$promono = $sXML->xpath("//item[promo='NO']");
foreach ( $promono as $value )    {
    $value = $sXML->item->addChild('newnode', '0');
}
unset($value);

$domDocument = dom_import_simplexml($sXML)->ownerDocument;
$domDocument->formatOutput = true;
echo $domDocument->save('new.xml'); 
?>

Любая помощь будет признательна.

Ответы [ 2 ]

1 голос
/ 21 марта 2019

Как вы можете сказать, все узлы добавляются к первому <item> узлу - это до строк ...

$value = $sXML->item->addChild('newnode', '1');

Когда вы начинаете с корневого узла и просто используете ->item->, это всегда будет предполагать, что вы хотите добавить новый узел к первому <item> элементу.

Вам просто нужно добавить узел к узлу $value. Я также упростил его, чтобы использовать 1 цикл, и он выбирает любые элементы <item> с элементом <promo> (используя //item[promo]). Затем добавляется новый узел с проверкой значения <promo> ...

$sXML = simplexml_load_file('file.xml', null, LIBXML_NOBLANKS);
$promo = $sXML->xpath("//item[promo]");
foreach ( $promo as $value )    {
    $value->newnode = ($value->promo=='YES')? 1:0;
}

$domDocument = dom_import_simplexml($sXML)->ownerDocument;
$domDocument->formatOutput = true;
$domDocument->save('new.xml'); 
1 голос
/ 21 марта 2019

Это проще всего сделать, используя DOMDocument самостоятельно.Вы можете использовать getElementsByTagName, чтобы найти все элементы promo, а затем добавить элемент newnode со значением, основанным на значении элемента promo:

$doc = new DOMDocument();
$doc->loadXML($xml);
foreach ($doc->getElementsByTagName('promo') as $ele) {
    $newnode = $doc->createElement('newnode');
    $newnode->nodeValue = $ele->nodeValue == 'YES' ? 1 : 0;
    $ele->parentNode->appendChild($newnode);
}
echo $doc->saveXML();

Демонстрация на 3v4l.org

...